本节摘要:本案例用顶点阶段的正弦叠加让平面网格起伏成水面,配合法线扰动与光滑度做出波光,再用距离与时间控制泡沫线。这是 Vertex 块第一次当主角,案例同时交代顶点动画的网格密度前提与阴影保真问题。
需求是一块二十乘二十米的主角池塘:近距离有起伏,岸边有随波涌动的泡沫线,水面反光要"活"。技术路线确认三件事:起伏在顶点阶段做(Position 端口,1.3 节的两阶段分工在此兑现);波光在片元阶段做法线扰动与光滑度;泡沫线用世界高度加时间的阈值切割(Step 的又一胜场)。
动手前有一个硬前提要先解决:顶点动画吃网格密度。默认立方体的六个面每面只有两个三角形,顶点稀疏到正弦波根本"没地方弯"。正确做法是用 Unity 自带平面(Plane)并把网格密度调高——20 乘 20 的分段在手机上是可接受规模,PC 可以到 64 乘 64。记住这个前提,它能解释日后"顶点动画怎么不动"的一大半案例。
新建 Unlit 图(水面后期会升级 Lit,先用 Unlit 看形状)。节点链:Position 节点(Object 空间)接 Split 拆出 X 与 Z(水面沿水平两轴起伏,Y 是波高);X 与 Z 各自与 Time 的 Sine Time 相加(Add),接 Sine 节点取正弦——注意这里用的是"对坐标加时间取正弦"的结构,波长与相位就藏在坐标系数里;两路正弦相加后乘波高属性 WaveHeight(默认 0.1),再加回原 Position 的 Y 分量(Add),合成新的三维位置接顶点块的 Position 端口。
保存后预览:平面像布料一样平缓起伏。调两个参数找感觉:WaveHeight 拉到 0.3 是惊涛,降到 0.02 是涟漪;想改波长,在 X 与 Z 进 Sine 之前各乘一个频率系数(做成属性 WaveFreq)——系数越大波越密。

形状对了再上质感,三个升级动作。升级一:换 Lit 图——水面要有反光才有"水"的认证:复制图改成 Lit 类型,Smoothness 拉到 0.9 以上,Base Color 接深蓝到青的渐变(按视角深度或简单常量起步)。升级二:法线扰动——把 4.3 节的滚动 UV 接一张法线噪声贴图的采样,输出接到 Lit 图的 Normal 端口(空间选 Tangent),反光碎成粼粼波光;两层不同速度、不同方向的法线叠加,波光的层次立刻出来——6.4 节结尾预告的"视差手法"在这里再次生效。升级三:岸边泡沫——Position(World 空间)的 Y 分量与时间驱动的阈值比较:Step(Sine Time 乘幅度加基准线, 世界 Y) 生成一条随水位涨落、边缘被噪声打散的白色泡沫带,用 Lerp 混进 Base Color。泡沫的"随波涌动"来自阈值随时间摆动,泡沫的"破碎感"来自噪声扰动坐标——两个旧零件各司其职。
阴影问题要单独交代:顶点动画改变了几何形状,但投影阴影默认仍按原始几何生成,起伏的水面投下的影子是"平的"。小池塘看不出,大湖会穿帮。URP 下的轻量对策是接受它(水面阴影本来就弱),或关闭水面投影只保留受影——阴影保真是顶点动画的知名遗留问题,知道成因与取舍即可,本册不展开管线级方案。
解读成本结构:本案例的顶点计算量随网格密度线性涨(两路正弦加四次乘加,每顶点十几次运算),片元侧的账在 Lit 升级后主要是两次法线采样。手机上二十乘二十网格加双法线是舒适区,PC 上翻倍也稳。变式一:熔岩——同一套起伏,颜色换黑红渐变,波光换 Emission 辉光,泡沫线换裂纹亮线(Voronoi 出场)。变式二:能量场——WaveHeight 加大到 0.5、频率拉高、颜色半透明加全息式闪烁,护盾波动就是这么来的。变式三:旗帜——只在 X 方向保留一路正弦、振幅随高度递增(乘 UV 的 V),布料飘动的最小实现。
💡 顶点动画的调试技巧:看不清波形时把 WaveHeight 临时拉到夸张值(比如 2),形状问题一目了然,调好再收回来——先放大再收敛,比在小数值里猜快得多。
调波形参数时肉眼观察起伏太慢,推荐一个土制波形仪:把水面图复制一份,顶点动画链原样接好,但把最终的波高输出同时引到 Base Color(灰度直显)——平面上每点的亮度就是波高,波纹形状一览无余,频率、振幅、叠加干涉全部可视化。调参在这个视图里进行,调好再把颜色链路换回来。一图两用,二十秒的搭建换十倍的调参效率。
阴影区的光照计算被简化,法线扰动的波光在阴影里几乎消失,观感上"阴影里的水是死的"。这是光照管线的正常行为而非 bug。缓解思路:阴影强度调低让水面少进全阴影;或接受差异——真实水面在阴影里的反光本来也弱。大场面项目会有专门的方案(如按需开关水面的阴影接收),学习阶段知道成因即可。
把本章两大案例的技能结构对照一遍,你会发现它们共享同一套底层能力:溶解的距离场与水面的泡沫阈值都是"数值切割"(Step 与 Smoothstep);溶解的噪声与水面的法线扰动都是"随机场"(6.3 节);两者的驱动都来自 Time 与属性的组合。案例不同,零件相同——这正是本书反复强调"节点族是弹药库"的原因:学透一打函数,案例只是排列组合。
第 6 章收尾,全书的案例体系(描边、全息、溶解、水面)就此齐装。下一章把这些成果收进"仓库":Sub Graph 封装、Custom Function 与 HLSL 的边界、关键字变体——工程化的三件套。