屏幕雨滴模拟
https://zhuanlan.zhihu.com/p/298606553
https://www.shadertoy.com/view/ltffzl
https://github.com/ya7gisa0/Unity-Raindrops
实现的困难难点:
水珠模拟
通过 length 对 UV 进行画圆,UV中心需要从左下角移动到中间
通过对 UV的x,y是均等缩放,配合 frac/num,实现变形效果
使用偏移后的UV,对贴图进行采样,达到扰动的效果
水珠流动的模拟
通过对 整体UV施加向下的偏移 uv.y += t * 0.25;
通过对 frac 后的uv.y,进行周期性偏移 uv.y = -sin(t + sin(t + sin(t) * 0.5)) * 0.45,实现周期性快速下落
通过对 frac 后的uv.x,进行周期性的偏移,uv.x = sin(3 * w) * pow(sin(w), 6) * 0.45; 实现突然的左右移动
使用 N21 伪随机方法,实现随机左右移动和上下移动
- // 求伪随机数
half N21(half2 p) { p = frac(p * half2(123.34, 345.45)); p += dot(p, p + 34.345); return frac(p.x + p.y); }
- // 求伪随机数
雨滴下落
水珠流动痕迹的模拟
- 通过对 UV.x 进行 abs后,然后使用较小的 smoothstep fogTrail *= smoothstep(0.5, y, gv.y);//将水滴做个渐变,从上到下从无到有, 0.5是以gv为坐标的,顶部0.5,底部-0.5
- 对 UV.y 方向也用smoothstep进行渐变计算 fogTrail *= smoothstep(0.05, 0.04, abs(dropPos.x) * _Test);// 两边雾的效果缩小下
小技巧
将UV零点移动到中心,可以使用 Length 和 SmoothStep 进行画圆,正反圆 Mask
half drop = smoothstep(0.5, 0, length(gv));
half drop = smoothstep(0, 0.5, length(gv));
将 UV的 y进行 frac 然后除以拉长程度,可以的到如下效果
half2 gv = frac(uv) - 0.5;//-0.5,将左下角的原点调整为中间
gv.y = (frac(gv.y * 1) - 0.25) / _Test;
half drop = smoothstep(0.05, 0.03, length(gv));//画圆, length(gv),可以理解为半径
将 frac 里面乘以2 如下:
gv.y = (frac(gv.y * 2) - 0.25) / _Test;