
Unity ShaderGraph实战5分钟打造动态水面效果水面效果是游戏开发中最常见的自然元素之一。想象一下当玩家走过湖边看到微风拂过水面泛起的涟漪或是暴风雨中汹涌的波涛这些动态效果都能极大提升游戏的沉浸感。传统的水面着色器编写需要深厚的图形学知识而ShaderGraph让这一切变得可视化且直观。本文将带你用UV和Time这两个核心Input节点快速实现一个基础但效果出众的动态水面。1. 准备工作与环境搭建在开始制作水面效果前我们需要确保开发环境配置正确。首先创建一个新的URP项目Universal Render Pipeline这是Unity推荐的现代渲染管线对ShaderGraph有更好的支持。在Unity Hub中新建项目时选择URP模板创建完成后在项目窗口中右键选择Create Shader Graph URP Unlit Shader Graph因为我们先实现基础效果后续可升级为PBR水面将新建的ShaderGraph命名为WaterSurface提示如果找不到ShaderGraph创建选项请确保已安装ShaderGraph包Window Package Manager中搜索安装接下来我们需要准备一张基础水面纹理。可以在任何素材网站搜索water normal map找到合适的法线贴图这将作为我们水面波纹的基础。将下载的贴图导入Unity后记得在Inspector中将Texture Type设置为Normal map。2. UV动画创造水面流动感UV动画是Shader中实现动态效果的核心技术之一。原理很简单通过随时间改变UV坐标让贴图移动起来。打开刚创建的WaterSurface ShaderGraph我们先建立基础的UV流动在空白处右键创建UV节点Input Geometry UV添加Time节点Input Basic Time创建Multiply节点将Time与一个Vector2常量连接如(0.02, 0.02)控制速度使用Add节点将UV和乘后的Time相加此时你的网络应该类似这样UV - Add Time - Multiply - Add Vector2(0.02,0.02) - Multiply这种基础UV动画会让整个贴图朝右下角匀速移动。但真实的水面运动更加复杂我们需要更丰富的层次感。3. 多层纹理混合增加水面细节单一方向的流动看起来会很假。专业的水面效果通常使用多层纹理以不同速度和方向混合复制刚才的UV动画网络创建第二套建议将速度改为(0.03, -0.01)为两套UV网络分别采样不同的法线贴图可使用同一张贴图但缩放不同添加Blend节点Normal Blend或Height Blend模式混合两个法线结果// 第一层UV动画 UV - Add1 Time - Multiply1 - Add1 Vector2(0.02,0.02) - Multiply1 // 第二层UV动画 UV - Add2 Time - Multiply2 - Add2 Vector2(0.03,-0.01) - Multiply2 // 采样与混合 Add1 - SampleTexture2D1 - Blend Add2 - SampleTexture2D2 - Blend注意纹理采样时建议将Wrap Mode设置为Repeat这样UV超出1.0时会自动平铺而非拉伸4. 添加顶点动画模拟波浪起伏仅有表面法线变化还不够真实水面会有高度起伏。我们可以用顶点位移来模拟创建Position节点Input Geometry Position使用之前混合的法线贴图的R或G通道代表水平方向的高度变化通过Remap节点将法线值从[0,1]映射到[-0.1,0.1]作为位移幅度将结果与原始Position相加后输出到Master节点的Position端口Blend - Split - R通道 - Remap(0,1,-0.1,0.1) - Add Position - Add - Master_Position为增强效果可以再添加一个基于世界XZ坐标的Sine波Position - Split - XZ - Multiply(0.5) - Sine - Multiply(0.05) - Add这样水面会有基础的大波浪运动配合之前的细节法线效果立即生动起来。5. 镜面反射与边缘光提升视觉质感基础动画完成后我们需要添加光学特性使水面更真实创建Normal Vector节点使用之前混合的法线结果添加View Direction节点并归一化使用Dot Product节点计算视角与法线的夹角通过Power节点控制高光强度如Power50输出到Master节点的Smoothness和SpecularBlend - NormalVector - DotProduct ViewDirection - Normalize - DotProduct DotProduct - Power(50) - Master_Specular边缘光Fresnel效应可以通过类似方式实现NormalVector - FresnelEffect - Master_Emission6. 参数优化与性能考量现在我们的水面已经具备基本所有元素最后需要调整参数并考虑性能速度控制建议将Time乘数设为可调参数右键Create Property幅度控制顶点位移和法线强度也应暴露为参数LOD处理远处水面可以简化计算纹理压缩确保法线贴图使用适当压缩格式如BC5/DXT5nm参数建议值参数建议值说明速度1(0.02,0.02)基础层流动速度速度2(0.03,-0.01)细节层流动速度位移幅度[-0.1,0.1]波浪高度范围高光强度50-100水面反光程度在项目中使用时可以根据相机距离动态调整这些参数远处水面可以减少纹理层数或禁用顶点动画。7. 进阶扩展思路基础效果实现后可以考虑以下增强方向焦散效果添加Caustics纹理动画模拟水下光斑泡沫系统在水体边缘或物体周围添加泡沫痕迹交互波纹通过脚本传递物体位置信息生成局部涟漪天气影响根据风雨强度参数化控制波浪幅度深度渐变浅水区更透明且波浪更明显实现交互波纹的简单方法在C#脚本中定义可交互物体位置数组通过Material.SetVectorArray传递到Shader在Shader中计算每个位置的距离并叠加波纹// C#脚本 public Transform[] interactObjects; private Vector4[] positions; void Update() { positions interactObjects.Select(t (Vector4)t.position).ToArray(); material.SetVectorArray(_InteractPositions, positions); }// Shader中 for(int i0; i_Count; i) { float dist distance(_InteractPositions[i].xyz, worldPos); float wave saturate(1-dist/_Radius) * sin(dist*_Frequency - _Time.y*_Speed); height wave * _Amplitude; }这种技术可以让角色走过水面时产生真实的涟漪扩散效果。