用Shader Graph重现水下气泡的银色魔法:全内反射实战指南
清晨的阳光穿透海面,一群气泡从珊瑚礁缝隙中升起。你有没有注意过,这些气泡表面总带着一层神秘的银色光泽?这种现象背后隐藏着光学中的全内反射原理。本文将带你用Unity Shader Graph,从零开始还原这种迷人的视觉效果。
1. 解密气泡银光的物理本质
水下气泡之所以呈现银色光泽,是因为光线在空气与水的界面发生了全内反射。当光线从高折射率介质(水)进入低折射率介质(空气)时,如果入射角大于临界角,所有光线都会被反射回来,形成镜面般的完美反射。
关键参数对比表:
| 参数 | 外部反射(水-空气) | 内部反射(空气-水) |
|---|---|---|
| 折射率比 | 1.33/1.0 | 1.0/1.33 |
| 临界角 | 48.75° | 无 |
| 菲涅耳曲线 | 平缓上升 | 陡峭上升至1.0 |
在Shader中模拟这一现象时,我们需要特别注意:
- 使用
Fresnel Effect节点时,Power参数需要调低(通常0.5-1.5) Normal Vector输入必须使用物体空间法线- 结合
Refraction节点实现光线弯曲效果
2. Shader Graph核心节点配置
2.1 基础反射网络搭建
创建一个新的Unlit Shader Graph,按以下步骤构建基础反射网络:
// 节点连接示例 FresnelEffect -> Color -> BaseColor NormalVector -> FresnelEffect.Normal关键参数设置:
FresnelEffect.Power: 1.2FresnelEffect.Bias: 0.1FresnelEffect.Strength: 0.8
2.2 添加折射效果
为了更真实地模拟水下环境,我们需要加入折射计算:
Refraction -> SceneColor -> BaseColor NormalVector -> Refraction.Normal提示:折射强度(IOR)建议设置为1.33,即水的折射率
3. 进阶效果优化技巧
3.1 动态波纹模拟
通过噪声纹理为气泡表面添加动态波纹效果:
- 导入噪声纹理(推荐使用Perlin Noise)
- 创建
Texture2D节点并连接至NormalMap节点 - 使用
Time节点驱动UV偏移
// 波纹动画实现 SimpleNoise -> NormalMap -> NormalVector Time -> Multiply -> Add -> Noise.UV3.2 多层反射叠加
真实气泡的反射往往包含多层光学效应:
- 主反射层:强全内反射(银色)
- 次反射层:微弱的环境光反射
- 边缘光:菲涅尔边缘增亮效果
节点组配置示例:
Layer1: FresnelEffect(Color=Silver, Power=1.0) Layer2: AmbientOcclusion(Intensity=0.3) Layer3: FresnelEffect(Color=White, Power=2.0)4. 性能优化与平台适配
4.1 移动端优化策略
针对移动设备的特殊优化方案:
| 优化项 | 桌面级效果 | 移动端替代方案 |
|---|---|---|
| 折射采样 | 全分辨率 | 半分辨率 |
| 反射计算 | 精确计算 | 近似预积分 |
| 波纹细节 | 动态计算 | 静态法线贴图 |
4.2 参数动态调节系统
创建可动态调节的材质参数:
[Header("Reflection Settings")] _ReflectionPower("Reflection Power", Range(0,2)) = 1.0 _ReflectionColor("Reflection Color", Color) = (0.8,0.8,0.9,1)在C#脚本中通过以下代码控制:
material.SetFloat("_ReflectionPower", intensity); material.SetColor("_ReflectionColor", newColor);5. 实战案例:气泡群渲染系统
当需要渲染大量气泡时,单个Shader需要与粒子系统配合:
- 在粒子系统中启用
Custom Vertex Streams - 添加
AgePercent和RandomValue流 - 在Shader中使用这些参数驱动反射强度变化
// 粒子参数应用 VertexStream.AgePercent -> Lerp(MinReflection, MaxReflection) VertexStream.RandomValue -> RotateUV注意:气泡群渲染时建议使用GPU Instancing提升性能
在最近的一个水下场景项目中,我发现将气泡的反射颜色略微偏向青色(RGB:0.7,0.8,0.9),能更好地融入水下环境光。同时,为每个气泡添加微小的随机旋转,可以打破重复感,使整体效果更加自然生动。