creator shader:从零开始,做个地面震动效果,类似冲击波?

creator shader:从零开始,做个地面震动效果,类似冲击波?

老帖子图片链接挂了,补个链接

从零开始的标题只是用惯了,下面的代码需要实验的话,请确保之前从零开始,用shader画个彩虹 21你能看明白或者你已经练习过。

上个效果

17659860995750.019454960019345657

改一个空的effect出来

下面用到了texture2D函数,用uv对图片采样,返回值是一个vec4,分量rgba就是图片采样结果,一个颜色值。

  void main () {
    vec2 uv = v_uv0;
    vec4 tex = texture2D(texture,uv);
    gl_FragColor = vec4(tex.xyz,tex.w);
  }

17659860995790.707069730960072

介绍一下原理

最近有个需求,角色攻击命中时,有有一个冲击波的效果,认真研究了原版,发现就是在攻击所在点的地面放了一个这种冲击波,看着挺有打击感。
这个冲击波说白了就是一个圈,然后向外扩散。

先做扩散的圈圈吧

画个圆圈,显示出来

画圆圈的之前介绍过,可以参考之前的画彩虹的帖子

u_time的实现可以参考之前的creator shader:从零开始 第二篇,做个动态的光影 8的帖子。

  void main () {
    // vec4 o = vec4(1, 1, 1, 1);
    vec2 uv = v_uv0;

    // 圆心
    vec2 p = vec2(.5,.7);

    // // 求到圆心距离
    vec2 off = p - uv;
    float dis = length(off);
    // // 圆半径
    float r = .02;
    // r += u_time * .6;
    // // 圆圈线宽
    float width = .005;
    // // 圆圈线边缘过渡区宽度
    float border = .01;

    // // 画圆
    float circle = smoothstep(r+width+border,r+width,dis) - smoothstep(r,r-border,dis);
    
    vec4 tex = texture2D(texture,uv);
// 图片正常颜色上,加上圆圈的值,圆圈的值取值范围是0-1 色彩的rgb也是0-1,加起来就是0-2 ,rgb全都>=1时显示白色, 这里加一下只是单纯的为了看看圆圈形状哈,么有什么意义,后面用这个circle的值做uv便宜,就能看到图片的变形了。这里线用白色显示,方便观察动画轨迹
    tex.xyz += circle;
    gl_FragColor = vec4(tex.xyz,tex.w);
  }

17659860995880.7647222770201793

让圆随着时间变大

    // 圆半径
    float r = .02;
    // 加上下面这一行
    r += u_time * .6;

这个效果就需要运行起来看了。截图gif太麻烦了,下一步直接一步到位吧

加上圆的大小限制

圆的强度需要随着圆变大而变弱,并且需要一个范围限制,不能让圆无限制变大

     // 边缘的宽度要随着圆半径变大而变宽 *30 是因为半径本身的值太小了,乘30倍吧
    border *= r * 30.5;

    // // 画圆
    float circle = smoothstep(r+width+border,r+width,dis) - smoothstep(r,r-border,dis);

    // // 强度小一点
    circle *= .4;
    // // 圆运动的最大边界
    circle *= max(.3 - dis,0.);

17659860995920.7162069582598994

到这里我觉得圆圈的变化范围已经可以了,把这个白圈变换成uv取样的偏移

   // uv-p 两点相减得到uv到圆心的方向向量,用向量*强度得到最终偏移,强度就是前面画的白圈的值
  uv = uv + (uv - p) * circle;
    vec4 tex = texture2D(texture,uv);
    //tex.xyz += circle;

这就是最终效果了,但是偏移是很不明显的,运行起来看半径变大后的直观。

圆圈变形了?

可以看到,前面的圆圈都是个椭圆,为啥呢,因为我的妞的 图片宽!=高。

   // 这一行放在main函数外面啊 传入图片的真实宽高,缩放off的uv
    #define iResolution vec2(647.,938.)

   .........下面是main函数里面的修改
    vec2 off = p - uv;
    off.x *= iResolution.x / iResolution.y;

17659860995950.8200360114867292
嘿嘿嘿,圆不圆?


公众号欢迎关注

17659861000750.2599713665486282

4赞

大佬,写点3.x吧

原理是一样的啊,3.x自己看看文档语法就行

交作业

jelly