效果预览
话不多说先上图。
树木,高草,顶棚与草地细节部分的动效均为着色器效果
具体实现:
右键在新标签页中打开图片查看细节
基本思路:
- 核心是使用Tiling And Offset节点与Gradient Noise节点在对象UV上制造随机扰动,以模拟自然风的效果
- 附加使用UV节点结合Power节点来限制扰动在对象上应用的范围
- 最后使用Lerp节点插值,应用最终效果
实现细节:
1.Split节点与Combine节点的使用
Split节点的用途是将n维矢量分离,这样就可以单独加工其中的任一维。而Combine节点则将这些向量重新结合在一起。
(第一次见这个RGBA给我看懵逼了,心想我输入的也不是颜色阿..后来查一下才知道RGBA只是输出矢量的标识)
2.将Time节点输入来平移噪声
Time节点是任何随时间变化的效果中必不可少的。
Time,DeltaTime与SmoothDelta可用于随时间推进而变化的效果,而Sine Time与Cosine Time则可以用于来回循环的效果。
3.使用Power节点与Lerp节点来固定作用范围
UV的取值范围为(0,1)
随着InfluenceHeight的增大,输出结果越来越极化,结合Lerp节点的定义可以固定扰动的作用范围,实现高草地下半部分不受影响的效果,更接近于现实中草地的表现。
个人感想:
- Add,Multiply,Subtract,Divide以及One Minus这些基本节点用处非常广泛,在学习时须熟练掌握其性质
- 若要仅更改某N维矢量的某一维度,先使用Split节点将其分离,再使用Combine节点组合在一起
- Gradient Noise节点可生成均匀自然的随机噪声,在模拟风,水波等自然效果时应用广泛
- 这个着色器瞎胡调参数能调出来好多神奇的效果..比如这个类似于穿梭的东西
我怀疑好多效果都是这样瞎调出来的..
小白一个,若有错误还请不吝指正啦。
参考链接:
https://forum.unity.com/threads/shader-graph-and-multiple-sprite-mode.706733/ 简单的抖动效果
https://blogs.unity3d.com/2018/10/05/art-that-moves-creating-animated-materials-with-shader-graph/ 官方3D示例项目+讲解
https://docs.unity3d.com/Packages/com.unity.shadergraph@9.0/manual/index.html 官方文档
根据人走过去才动的草丛 2D要怎么做啊?
@Maikid:如果要用着色器实现的话,我感觉可以加一个box collider触发器,再用脚本把着色器参数和触发器连在一起(不过那样的话可能就要为每个草丛单独建材质了..太麻烦)
@Onyx:不需要啊,一个材质就行了
@三页:对,我刚才试着写了一下,Unity会在运行时创建副本,的确只用一个材质就够了。是我想当然了。
感谢分享
我是把这个Material给了整个tilemap,我这个tilemap里面全是各种树木,问题来了,shader里最后的MainTex变量,如何取到每一种树木?示例里看起来是单个texture赋值的?
@erddddd:Unity的Tilemap中,每个Tile的UV和局部空间都是单独计算的,所以如果一棵树木是多个Tile拼成的,那么用基于UV的材质就会每个Tile自己抖自己的,这个似乎是没什么办法。可以把需要类似特殊材质的东西单独分成完整的Sprite再应用不同的材质。
@Onyx:搞定了,MainTex变量的Reference属性写成 _MainTex 就行了,这好像是shader的内部变量名,会自动取到每一个贴图,不用手动赋值。
文中是顶部受风,底部保持不动。
如果想改成外部受风,内部不动,应该怎么改?
我尝试使用Ellipse圆形节点做差值依据(圆内的不动,圆外的动),但不能连接lerp的T输入,尝试用"菲涅尔"节点,能是能连,但效果不是想要的。
@erddddd:菲涅尔节点的核心算法是NdotV,就是法线方向点乘视线方向(或者你喂进去的其它矢量参数),两者夹角为0时点乘结果最小为0,夹角90度时点乘结果最大为1,而三维模型中模型外侧的法线与视线的夹角基本都会比内部大,所以就可以用菲涅尔来取到模型边缘的区域。
而2D精灵本质是一个平面,它的法线只会朝一个方向,这种情况下菲涅尔就莫得用了。
想要取到平面的中心区域可以通过UV计算出来。比较近似的方法可以是
max(max(UV.x, 1-UV.x), max(UV.y, 1-UV.y)),之后通过power或者smoothstep来调整区域范围。
@Onyx:尝试了一下,方案可行!实在是太感谢了!
对菲涅尔节点的原理讲解帮助太大了,对于我这种初学shader的来说,最大的障碍就是不明白其中的原理,不知道“为啥不可以”,这解答对我帮助很大,再次感谢!