Unity Shader Graph - 程序性游鱼动画
Vertex 着色器程序性游鱼效果的核心原理与数学基础
游鱼的视觉本质与空间运动模拟
Vertex 着色器程序性游鱼效果本质是在三维空间中构建周期性的有机体纹理,并结合正弦波动力学、流体动力学等数学模型,模拟出"游动"的动态视觉特征。其核心数学逻辑围绕以下两点展开:
- 形态周期性:利用三角函数(正弦/余弦)的周期性,在曲面空间坐标上构建自然的鱼形轮廓,游鱼的体型、尾鳍摆动由正弦波的频率和相位控制。
- 动态游动驱动:将时间变量与流体速度场融入运动方程,使游鱼沿指定路径(如环形、直线、波浪形)持续移动,形成"游动"的动态效果。
关键数学特性
- 贝塞尔曲线映射:将空间坐标投影到参数化的贝塞尔曲线上,实现鱼群的自然集群运动轨迹。
- 值域约束与颜色映射:通过值域映射将 -1,1 的正弦输出转换为 0,1 的灰度值,或直接作为遮罩控制游鱼的显示/隐藏、透明度变化。
- 群体行为一致性 :通过对空间位置的分量组合(如
pos * frequency + time * speed),可实现所有游鱼遵循相似的游动规律,同时通过随机相位产生个体差异。
程序性游鱼动画效果的 Shader Graph 节点设计
核心节点功能概述
在 Unity Vertex Shader Graph 中实现程序性游鱼动画效果,需整合空间坐标、时间、贝塞尔曲线、法线扰动等节点,核心功能包括:
- 空间位置采样:获取模型的世界空间/对象空间坐标,作为游鱼的运动轨迹基准,支持不同空间下的游动效果(对象空间游动随模型旋转)。
- 动态时间驱动:通过 Time 节点获取实时时间,控制游鱼的游动速度和节奏,支持速度调节、方向反转。
- 有机体轮廓生成:利用正弦函数构建鱼形轮廓,结合频率参数控制体型大小,相位参数控制初始偏移。
- 流体运动模拟:将游鱼与流体场相结合,通过噪声节点(Simplex Noise/FBM)产生自然的泳动效果。
关键端口与参数定义
实现 Vertex 着色器程序性游鱼动画的核心参数端口设计如下:
| 端口名称 | 类型 | 功能说明 |
|---|---|---|
| World Position | Vector3 | 输入(只读),模型顶点的世界空间坐标,作为游鱼的运动基准 |
| Time | Float | 输入(只读),实时时间变量,驱动游鱼的动态游动 |
| Fish Count | Float | 输入(可调节),游鱼数量(用于实例化/粒子系统) |
| Swim Speed | Float | 输入(可调节),游鱼的游动速度(值为负时反向游动) |
| Swim Direction | Vector3 | 输入(可调节),游鱼的游动方向(如 XZ 平面方向,默认 (0,0,1)) |
| Fish Color | Color | 输入(可调节),游鱼的显示颜色,支持 Alpha 通道控制透明度 |
| Fish Size | Float | 输入(可调节),游鱼的大小/体型(值越大,体型越宽大) |
| Tail Frequency | Float | 输入(可调节),尾鳍摆动的频率(值越大,摆动越快) |
| Swim Path Radius | Float | 输入(可调节),游动路径的曲率半径(0 为直线,越大弧度越弯) |
| Base Color | Color | 输入(可调节),模型的基础颜色,游鱼将叠加于该颜色之上 |
| Out Color | Vector4 | 输出,最终的着色器颜色,用于连接到 Master 节点的 Base Color/Emission 端口 |
程序性游鱼动画效果的实现步骤(可复现)
前置准备
- 环境要求:Unity 2021.3+,URP(Universal Render Pipeline)渲染管线,已安装 Shader Graph 插件。
- 素材准备:任意 3D 模型(如 Sphere、自定义鱼形 Mesh),用于测试游鱼效果。
- 创建基础 Shader :
- 在 Project 窗口右键→Create→Shader→Universal Render Pipeline→Lit Shader Graph,命名为"ProceduralFishVertexShader"。
- 双击打开 Vertex Shader Graph,确认 Master 节点为 URP Lit Master。
步骤 1:获取空间坐标与时间变量
- 添加 World Position 节点:右键搜索"World Position"并添加,该节点输出模型每个顶点的世界空间坐标(x,y,z)。
- 添加 Time 节点:右键搜索"Time"并添加,选择"Time > Float"(取 Time 节点的 Time 分量,线性递增的时间值)。
- 添加 Vector3 节点:命名为"Swim Direction",默认值设为 (0,0,1)(沿 Z 轴游动),作为游鱼的游动方向基准。
步骤 2:构建游鱼的运动轨迹
- 位置投影 :将 3D 空间坐标投影到游动方向的 2D 平面,实现步骤:
- 添加"Split"节点,拆分 World Position 的 X、Z 分量(如需沿 Y 轴游动则拆 X、Y)。
- 添加"Multiply"节点,将 Split 后的 X 分量与 Swim Direction 的 X 分量相乘,Z 分量与 Swim Direction 的 Z 分量相乘。
- 添加"Add"节点,将上述两个 Multiply 的结果相加,得到投影后的一维坐标(命名为"ProjectedCoord")。
- 周期性轨迹计算 :
- 添加"Multiply"节点,将 ProjectedCoord 与"Swim Path Frequency"(新建 Float 节点,默认值设为 5)相乘,控制游动路径曲率。
- 添加"Multiply"节点,将 Time 节点的输出与"Swim Speed"(新建 Float 节点,默认值设为 2)相乘,控制游动速度。
- 添加"Sine 节点",将上述结果作为输入,输出周期性的波动值。
步骤 3:游鱼的体型与轮廓生成
- 体型控制 :
- 添加"Remap"节点,将 Sine 节点的输出(Input Min=-1, Input Max=1)映射到(Output Min=0, Output Max=Fish Size),得到 0,1×FishSize 范围的体型值。
- 轮廓生成 :
- 添加"Fresnel Effect"节点,将 Fresnel 的输出连接到 In 端口,模拟游鱼的边缘高亮效果。
- 将 Fresnel 与 Fish Size 的乘积作为游鱼轮廓的基础,实现自然的体型渐变。
步骤 4:颜色叠加与最终输出
- 游鱼颜色混合 :
- 添加"Multiply"节点,将 Fish Color(新建 Color 节点,默认值设为 (0,1,0,1),青绿色)与轮廓遮罩相乘,得到游鱼的颜色。
- 添加"Add"节点,将上述结果与 Base Color 混合,得到最终的混合颜色。
- 连接到 Master 节点 :
- 将最终混合颜色的输出连接到 URP Lit Master 节点的"Base Color"端口;若需游鱼自发光,可同时连接到"Emission"端口。
步骤 5:保存并应用 Shader
- 点击 Shader Graph 窗口的"Save Asset"保存着色器。
- 在 Project 窗口右键→Create→Material,命名为"ProceduralFishMaterial",将 Shader 赋值为上述创建的"ProceduralFishVertexShader"。
- 将该材质赋予场景中的 3D 模型(如 Sphere),进入 Play 模式即可看到动态游鱼动画效果。
程序性游鱼动画效果的实战调优与扩展案例
基础案例:沿直线游动的鱼群(角色伴游效果)
场景描述
在游戏中实现角色的"游鱼伴侣"效果,游鱼沿 Z 轴直线游动,模拟水下/科技感生物的伴随特征。
调整步骤
- 修改游动方向:将 Swim Direction 节点的 X 设为 0,Y 设为 0,Z 设为 1(沿 Z 轴游动)。
- 调整参数 :
- Swim Path Frequency:设为 5(直线游动频率)。
- Swim Speed:设为 3(游动速度更快)。
- Fish Size:设为 0.8(适中的体型)。
- Tail Frequency:设为 2(尾鳍摆动自然)。
- Fish Color:设为 (0,1,0,0.5)(半透明青绿色)。
- 增强效果:将游鱼颜色连接到 Emission 端口,Emission 强度设为 1,使游鱼微微发光,暗场景下更突出。
进阶案例:环形游动路径(水母/精灵效果)
场景描述
实现以模型中心为圆心的环形游鱼动画,模拟水族箱中的游鱼环绕效果。
实现步骤
-
替换空间坐标计算:
- 添加"Position"节点,选择"Object Space"(对象空间坐标)。
- 添加"Distance"节点,计算 Object Space 坐标到模型中心(0,0,0)的距离。
- 将 Distance 的输出与 Swim Path Radius 相乘,实现环形轨迹:
ringCoord = distance * radius + time * speed。
-
参数调整:
- Swim Path Frequency:设为 8(环形游动频率)。
- Swim Speed:设为 4(游动速度更快)。
- Fish Size:设为 0.6(较小的体型)。
-
效果增强:添加"Simplex Noise"节点,将噪声输出与游鱼颜色混合,产生自然的个体差异。
程序性游鱼动画效果的使用技巧与注意事项
空间坐标选择
- 对象空间(Object Space):游鱼随模型旋转而旋转,适合角色、道具的游鱼伴侣效果。
- 世界空间(World Space):游鱼固定于场景,模型移动时游鱼穿过模型,适合场景范围的生物群效果。
性能优化
- 减少节点复杂度:将重复的计算逻辑封装为"Sub Graph",减少主 Vertex Shader Graph 的节点数量。
- 控制频率与精度:水下/水下模拟场景下,Swim Path Frequency 建议不超过 15,避免过度密集的计算;Time 节点可使用"Time > Smooth Time"替代线性 Time,减少机械感的同时降低计算波动。
- LOD 适配:为不同 LOD 等级的模型设置不同的游鱼参数(低 LOD 降低数量、增大体型)。
视觉增强技巧
- 游鱼渐变 :将轮廓遮罩替换为"Smooth Step"节点,实现游鱼边缘的渐变效果,避免生硬的二值化边界,公式:
smoothstep(threshold - 0.05, threshold + 0.05, remapValue)。 - 游鱼闪烁 :在 Time 节点后添加"Sine"节点,控制游鱼的亮度周期性变化,公式:
scanIntensity = 1 + 0.5 * sin(time * 5),再将该值与游鱼颜色相乘。 - 深度衰减 :结合"Depth"节点,使远距离的游鱼透明度降低,增强空间层次感,公式:
scanAlpha = 1 - (depth / maxDepth)。
常见问题排查
- 游鱼不显示:检查轮廓遮罩是否合理(建议 0.1~0.8),确认游动方向是否正确(如沿 Y 轴游动却用了 XZ 坐标)。
- 游鱼卡顿:降低 Swim Path Frequency 值,或使用"Time > Delta Time"替代实时 Time,避免帧率波动导致的游动速度不均。
- 游鱼方向错误:调整 Swim Direction 的分量(如沿 X 轴游动设为 (1,0),沿对角线设为 (1,1)),或更换空间坐标(如 Object Space 替代 World Space)。
总结与拓展应用
总结
Unity Vertex Shader Graph 中的程序性游鱼动画效果核心是通过"空间坐标投影 + 正弦周期驱动 + 时间动态控制",实现从静态轮廓到动态游鱼的视觉转换。通过调整频率、速度、方向、体型等参数,可适配水下生物、精灵伴随、科技粒子等多种游戏/可视化需求,且节点化的实现方式无需编写手写 Shader,降低了开发门槛。
拓展应用
- 扫描高亮交互:结合射线检测,当游鱼经过模型的特定区域时,触发高亮/变色效果,用于解谜游戏的线索提示。
- 游鱼数据可视化:将游鱼的游动速度与模型的顶点数据(如速度场、流体密度)绑定,实现 3D 模型的数据分析可视化(如工业检测、医疗扫描)。
- 多通道游鱼:将游鱼分为红、绿、蓝三个颜色通道,分别控制不同的移动速度和方向,实现 RGB 分离的游鱼特效,用于赛博朋克风格场景。
【Unity Shader Graph 使用与特效实现】专栏 - 直达 (欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)