一.雨滴流淌着色器
法线贴图在红色通道和绿色通道上,那是法线的X轴和Y轴,在蓝色通道中 我有个用于雨滴流淌的蒙版,在Alpha通道中,有个时间偏移蒙版。这些贴图都是可以在PS上制作做来的,雨滴流淌图可以直接用笔刷画出来然后模糊下线,然后可以将这个图作为高度图并使用NVIDIA Photoshop插件将其转换为法线贴图
直接输出以后是这样的效果,但是我不想用UV坐标把它投射到立方体上,实际上我想把它们投射到世界空间中,这样不管物体有多大,也不管物体去哪里或者如何旋转,这些小水流将始终保持向上和向下的方向
所以我们使用绝对世界位置来采样,要把世界位置乘上一个稍小的数字得到正确的比例 ,但是在另一边出现了非常奇怪的拉伸,所以现在只是侧面和上面的效果是正确的,但是前面和后面是不对的,通常这种情况可能会采样两种不同的纹理并将它们混合一起,但是我们可以采用更高效的方式,我们可以分别为正面和侧面生成纹理坐标,然后将它们混合在一起

然后根据顶点法线判断面的朝向,获取顶点法线的R通道,你可以看到它只在X方向上是白色的,G通道只在Y方向是白色的,所以可以用这两个mask当作lerp的参数就可以获得两组UV坐标


然后根据法线的R通道判断当前位置是否是正面,然后根据这个决定使用哪个UV坐标

接下俩需要的是,一个随着时间流逝而流下雨水的动态蒙版,这是一个4x512像素的纹理,这个纹理上面部分是黑色然后有一块白色,然后变成灰色然后渐变成黑色,所以这就是水滴蒙版
我们仍然使用绝对世界位置采样,乘上一个值来进行缩放。

然后根据Alpha通道的时间偏移蒙版来让它动起来,
接着我们想要创造一种差异,比如水在不同的表面的流动速度是不一样的 。所以分别设置两个表面的流动速度,然后根据透水度进行插值,最后乘上B通道雨滴流淌的Mask

但是我们真正想做的是创建法线,只要将法线贴图采样后与之前计算的蒙版相乘即可,但是如果切换成球体就可以发现顶部的水滴看起来很奇怪,所以需要再做一个mask来消除着这种效果,

我们希望效果只出现在水滴会流下的那些侧面,所以增加了一个中间层的mask乘上之前的蒙版

最后我们还可以根据流淌的水滴更改一下粗糙度。

二.雨水涟漪着色器
首先需要一个简单的径向渐变纹理

首先我们要制作一个涟漪效果,可以取时间节点的小数部分然后减一可以得到一个-1到0之间不断循环的数,这样就可以得到一个循环变大的图案,接着乘上一个值提高对比度,然后限制到一个范围内,需要使用sin节点得到正弦波的效果。因为默认周期是1,所以最好更改周期为2PI,,然后还要制作一个逐渐消失的效果,因为时间节点的小数部分不断变大,用1-x就可以得到一个逐渐变小至0的数,最后乘上之前的正弦波
接下来就是将这个mask转换成法线,要改变一下现在的纹理。
这是新贴图的GB通道,是一个锥体的法线,R通道是之前的径向渐变纹理

然后就是获取法线,事实上如果追求精确的话法线的z值是可以推导出来的,这里使用1作为z值只是一个性能优化,但是这在数学上是不正确的,但会让程序运行的更快一些,现在已经出现了一个锥形的法线,接下来在蒙版的基础上制作动态的法线

效果很不错,接下来就是要创建一大堆涟漪
只要创建一个纹理,上面有很多个之前那样的贴图,并且在alpha通道设置了一个时间偏移贴图用来控制涟漪在不同的时间产生
然后只需要用时间节点加上贴图的Alpha通道,这里将粗糙度设置成0方便观看


其实还可以加上一个参数控制涟漪的强度,但是现实中很多涟漪是相互重叠的,所以接下来要完成重叠的部分。我们需要用这个着色器中的所有这些节点,进行多次操作然后相加,所以有必要把所有这些节点全部变成一个函数节点。这里淡化节点的方法修改了一下,增加了一个权重控制。

然后新创建一个材质函数多次调用这个材质函数,使用不同的时间值:不同的UV值和不同的权重值,让每个副本都有不同的尺寸,以不同的速度循环,并放置在空间里的不同位置。
先是设置不同的时间,乘1.6是总速度

接着设置不同的UV坐标,分别加和乘不同的值,这样我就能得到不同大小和尺寸的涟漪

最后是设置权重,我把权重减去0.25,0.5,0.75,然后乘上4,这样我就有了四组不同的涟漪,根据雨的强度而调节,如果强度值为1,就可以得到全部涟漪

最后把这些值传递给我的4个涟漪函数,然后混合这四个法线,这里还需要创建一个材质函数,先把四个法线的xy分量乘上四个权重分量,然后相加,四个法线的z分量合并成一个向量,基于权重值将1和法线合并向量插值,然后将四个分量相乘,最后与xy合并并且归一化。

好,合并法线以后连接到输出节点

最后创建一个新的材质测试一下这个材质函数,效果非常棒

