水面倒影是提升3D场景真实感的关键细节。传统实现方案往往需要复杂的光照计算或昂贵的屏幕空间反射(SSR),而Unity 2021.3.6f1版本中的ShaderGraph配合RenderTexture提供了一种轻量级解决方案。本文将手把手带你用5个核心步骤实现可动态响应的水面倒影效果。
水面倒影的本质是场景的镜像投影。我们通过三个技术组件实现这一效果:
需要准备的Unity工程配置:
提示:测试阶段可将水面平面设为亮色材质以便观察
在Project窗口右键创建 → Rendering → Render Texture,命名为"WaterReflectionRT"。关键参数设置:
| 参数 | 建议值 | 说明 |
|---|---|---|
| Size | 1024 | 分辨率越高效果越清晰 |
| Depth Buffer | Disabled | 本方案不需要深度信息 |
| Anti-Aliasing | 2x MSAA | 减少反射边缘锯齿 |
csharp复制// 挂载到反射相机的配置脚本
void Update() {
var mainCam = Camera.main;
transform.position = CalculateMirrorPosition(mainCam.transform);
transform.rotation = CalculateMirrorRotation(mainCam.transform);
}
Vector3 CalculateMirrorPosition(Transform source) {
var waterHeight = transform.parent.position.y;
var pos = source.position;
pos.y = waterHeight * 2 - pos.y; // 镜像Y坐标
return pos;
}
创建Unlit ShaderGraph并配置关键节点:
纹理采样:
透明度控制:
python复制# 节点连接示意
[Texture2D] → [BaseColor]
[ScreenPosition] → [TilingAndOffset] → [UV]
[FloatParameter] → [Alpha] → [Fragment]
波纹扰动(可选增强效果):
注意:最终材质应设为Transparent渲染模式
通过脚本控制反射相机的渲染间隔:
csharp复制[SerializeField] private float updateInterval = 0.1f;
private float timer;
void Update() {
timer += Time.deltaTime;
if(timer >= updateInterval) {
RenderReflection();
timer = 0;
}
}
根据主相机距离动态改变RenderTexture尺寸:
| 距离 | 建议分辨率 | 适用场景 |
|---|---|---|
| <5m | 2048 | 特写镜头 |
| 5-20m | 1024 | 常规视角 |
| >20m | 512 | 远景优化 |
问题1:倒影出现断裂
问题2:反射边缘模糊
python复制[Texture2D] → [Sharpen] → [BaseColor]
强度建议0.2-0.5
问题3:性能消耗过高
实际项目中,这套方案在RTX 3060显卡上可实现100FPS以上的稳定运行。关键在于根据场景复杂度平衡效果与性能,比如动态物体使用高精度反射,静态环境则可以采用烘焙反射贴图混合的方式。