【从UnityURP开始探索游戏渲染】专栏-直达
兰伯特漫反射的能量守恒性
能量守恒基本原理
在物理正确的渲染中,能量守恒要求:
- 表面反射的光能总量 ≤ 入射光能
- 漫反射+高光反射 ≤ 1.0
- 没有能量凭空产生或消失
经典兰伯特模型的能量守恒问题
传统兰伯特漫反射公式:
$漫反射 = 表面反照率 × max(0, N·L)$
不守恒的原因:
- 缺乏归一化因子:
- 半球积分结果应为π,但兰伯特模型直接使用N·L
- 正确公式应为:$漫反射 = 表面反照率 / π × max(0, N·L)$
- 反射率超标:
- 当反照率(albedo)设为1.0时,反射率可能超过100%
- 例如:N·L=1时反射率为100%,但实际应有吸收损失
- 恒定反射率:
- 对所有入射角使用相同反射率
- 现实中菲涅尔效应导致掠射角反射率增加
URP中的修正方案
Unity URP采用改进的兰伯特模型:- hlsl
- // URP实际实现(Lighting.hlsl)
- half diffuseTerm = saturate(dot(normal, lightDir));
- half3 diffuse = albedo * lightColor * diffuseTerm * INV_PI;
复制代码 其中:
- INV_PI ≈ 0.31831 (1/π)
- 通过除以π实现能量归一化
PBR工作流兼容性分析
兼容性类型
兼容维度支持情况说明数据输入✅ 完全兼容使用相同的albedo贴图输入光照计算⚠️ 部分兼容缺乏物理反射特性材质工作流✅ 完全兼容支持标准材质参数后期处理✅ 完全兼容兼容HDR/Bloom等效果全局光照⚠️ 有限兼容需要特殊处理完全兼容的方面
- 材质参数统一:
- 使用相同的albedo纹理和颜色参数
- 支持相同的法线贴图格式
- HDR管线整合:
- 后期处理协同:
- 与Bloom效果无缝配合
- 支持屏幕空间环境光遮蔽(SSAO)
有限兼容的方面
<ul>能量守恒缺口:
graph LRA[入射光能量] --> B[经验模型]B --> C[漫反射输出]C --> D{能量总和}D --> |100%| E[违反守恒]D --> |物理模型 |