Shader 特效——“水面波纹消散” 的实现

视频效果:

bilibili:

Shader 特效——水面波纹消散

youku:

Shader 特效——水面波纹消散

 

图片效果:

原理详解:

算法的核心就是模拟水波纹,对此我们使用以下数学公式

z_{x} = x * (sin( progress*(sqrt(x^2+y^2)*100. - 50.) )+.5)/30. -0.5\leq x \leq 0.5, -0.5\leq y \leq 0.5

z_{y} = y * (sin( progress*(sqrt(x^2+y^2)*100. - 50.) )+.5)/30. -0.5\leq x \leq 0.5, -0.5\leq y \leq 0.5

然后使用二者作为纹理坐标的偏移量 Offset,即可。

 以 z_{x} 为例,取 progress = 0.5 后其三维示意图等高线图如下:

z_{x} 示意图

完整代码与注释:

float amplitude = 100.0;
float speed = 50.0;

#define PI 3.141592653589
#define PI_HALF (PI/2.)

#iChannel0 "file://./images/11.jpg"
#iChannel1 "file://./images/13.jpg"

float progress = 0.f;

vec4 getFromColor(vec2 uv)
{
    return texture2D(iChannel0, uv);
}

vec4 getToColor(vec2 uv)
{
    return texture2D(iChannel1, uv);
}

vec4 transition (vec2 uv)
{
    vec2 dir = uv - vec2(.5);
    float dist = length(dir);
    
    /// 水面波纹的纹理偏移量,随着 progress 的增加,波纹会逐渐外扩并变大。
    /// z = x * (sin( progress*(sqrt(x^2+y^2)*100. - 50.) )+.5)/30.
    vec2 offset = dir * (sin(progress * (dist * amplitude - speed)) + .5) / 30.;
    
return mix(
               getFromColor(uv + offset),    ///< 用于源纹理
               getToColor(uv),
               smoothstep(0., 1.0, progress)
           );
}

void main()
{
    vec2 uv = gl_FragCoord.xy / iResolution.xy;

    progress = fract(.5 * iTime); ///< 线性速度

    gl_FragColor = transition(uv);
}
发布了237 篇原创文章 · 获赞 223 · 访问量 107万+

猜你喜欢

转载自blog.csdn.net/panda1234lee/article/details/104271886