从零开始的标题只是用惯了,下面的代码需要实验的话,请确保之前真正的从零开始的帖子你能看明白或者你已经练习过。
上个效果
改一个空的effect出来
下面用到了texture2D函数,用uv对图片采样,返回值是一个vec4,分量rgba就是图片采样结果,一个颜色值。
void main () {
vec2 uv = v_uv0;
vec4 tex = texture2D(texture,uv);
gl_FragColor = vec4(tex.xyz,tex.w);
}
介绍一下原理
最近有个需求,角色攻击命中时,有有一个冲击波的效果,认真研究了原版,发现就是在攻击所在点的地面放了一个这种冲击波,看着挺有打击感。
这个冲击波说白了就是一个圈,然后向外扩散。
先做扩散的圈圈吧
画个圆圈,显示出来
画圆圈的之前介绍过,可以参考之前的画彩虹的帖子
u_time的实现可以参考之前的光影特效的帖子。
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);
}
让圆随着时间变大
// 圆半径
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.);
到这里我觉得圆圈的变化范围已经可以了,把这个白圈变换成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;
嘿嘿嘿,圆不圆?