本篇记录下可交互的瀑布水的案例制作流程。使用的工具为shader graph,制作内容包括流动的水与水流被障碍阻挡分流的逻辑,网上有类似的教程但是只有图没有原理,看本篇就对了该有的都有。

制作流动的水

通用控制UV技巧

控制UV位置变化的节点组合

通过time控制uv朝着Y移动

给水添加顶点动画


算法解析:

1
计算后的顶点高度 = 当前顶点位置 + Y轴高度(法线(normal) * 噪声随机数(float))

制作水流被阻挡效果

总的思路是做透明遮罩,先画个圆再画个垂直面上的透明遮罩两者拼接

相当于下面的伪代码:

1
saturate(lerp(TopdownMask,SphereMask,LerpMask))

这个lerpMask参数会判定给定的像素点在当前像素点的上方还是下方(0,1),如果在上方则使用SphereMask计算遮罩参数,反之使用TopdownMask的值,最后将这个值规范到0-1内(clamp截断超过的值)。

计算X轴的遮罩(垂直方向上的透明区)


这里用到distane函数,他会返回两点距离,这个距离永远是正的。所以这边的topdown_radius就是半径.

1
2
return distance(target.xz,self.xz) - 1
--将z引入是判定target距离当前plane面的距离

计算球体遮罩

1
2
return distance(target.xyz,self.xyz) - 1
--球体的判定有俩个纬度xy

计算差值


我们希望低于当前y轴的部分做矩形遮罩,高于的话做圆形遮罩
相当于下面的伪代码:

1
2
3
4
5
if([target].y - [self].y > 0)
return 0
else
return 1
--给定的像素点高于当前就返回0 否则返回1

完成

参考链接与资源

本篇资源已经上传github:https://github.com/KeyleXiao/waterfall_effect
参考youtube视频:https://www.youtube.com/watch?v=4X9ak_SjNwU