【从UnityURP开始探索游戏渲染】专栏-直达
几何遮蔽的基本流程
几何遮蔽(G)在BRDF中用于模拟微表面间的自阴影和遮蔽效应,其计算流程通常分为三个步骤:
- 遮蔽项计算:光线入射方向的遮挡概率
- 阴影项计算:视线方向的遮挡概率
- 联合计算:将两者结合形成完整的几何函数
主要几何遮蔽模型
1. Cook-Torrance模型
原理:
- 基于V形微槽假设
- 使用简单的min函数计算遮蔽和阴影
公式:
G_{Cook-Torrance}=min(1,\\frac{2(n⋅h)(n⋅v)}{v⋅h},\\frac{2(n⋅h)(n⋅l)}{v⋅h})
特点:
- 计算简单但不够精确
- 在掠射角表现不佳
2. Smith模型
原理:
- 将几何项分解为独立的遮蔽和阴影项
- 假设微表面高度服从统计分布
公式:
G_{Smith}=G_1(v)⋅G_1(l)
Unity URP选择:
c
hlsl
// URP中Smith联合Schlick-GGX实现
float V_SmithGGX(float NdotL, float NdotV, float roughness)
{
float a = roughness;
float a2 = a * a;
float GGXV = NdotL * sqrt(NdotV * NdotV * (1.0 - a2) + a2);
float GGXL = NdotV * sqrt(NdotL * NdotL * (1.0 - a2) + a2);
return 0.5 / max((GGXV + GGXL), 0.000001);
}
选择原因:
- 与GGX法线分布完美匹配
- 能量守恒性更好
- 计算效率较高
3. Schlick近似模型
原理:
- 对Smith模型的快速近似
- 使用有理函数替代复杂计算
公式:
G_{Schlick}(n,v)=\\frac{n⋅v}{(n⋅v)(1−k)+k},k=\\frac{(α+1)\^2}8
特点:
- 适合移动端等性能受限平台
- 精度略低于完整Smith模型
4. Kelemen-Szirmay-Kalos模型
原理:
- 基于微表面斜率分布
- 特别适合各向异性材质
公式:
G_{KSK}=\\frac1{1+Λ(v)+Λ(l)}
应用场景:
- 头发、织物等特殊材质渲染
Unity URP的实现方案
选择方案:Smith-Joint-Schlick-GGX
实现代码:
c
hlsl
// Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
{
float a2 = roughness * roughness;
float lambdaV = NdotL * (NdotV * (1.0 - a2) + a2);
float lambdaL = NdotV * (NdotL * (1.0 - a2) + a2);
return 0.5 / (lambdaV + lambdaL + 1e-5f);
}
选择原因:
- 物理准确性 :
- 与GGX NDF保持数学一致性
- 满足能量守恒和互易性
- 视觉质量 :
- 在掠射角产生自然的阴影衰减
- 粗糙材质表现更真实
- 性能平衡 :
- 相比完整Smith模型减少30%计算量
- 移动端友好(无复杂数学函数)
- 材质一致性 :
- 与金属/粗糙度工作流完美配合
- 参数响应线性度好
优化技术
-
预计算部分项:
chlsl // 预计算粗糙度平方 float a2 = roughness * roughness;
-
数值稳定性处理:
chlsl // 避免除零错误 return 0.5 / (lambdaV + lambdaL + 1e-5f);
-
移动端简化版:
chlsl #if defined(SHADER_API_MOBILE) float V_SmithMobile(float NdotL, float NdotV, float roughness) { float a = roughness; float GGXV = NdotL * (NdotV * (1.0 - a) + a); float GGXL = NdotV * (NdotL * (1.0 - a) + a); return 0.5 / (GGXV + GGXL); } #endif
各模型性能对比
模型 | 指令数 | 特殊函数 | 移动端适用性 | 视觉质量 |
---|---|---|---|---|
Cook-Torrance | 8 | 无 | ★★★★☆ | ★★☆☆☆ |
Smith完整版 | 15+ | sqrt | ★★☆☆☆ | ★★★★☆ |
Smith-Schlick | 10 | 无 | ★★★★☆ | ★★★☆☆ |
URP实现 | 12 | sqrt | ★★★☆☆ | ★★★★☆ |
Kelemen | 18+ | 复杂运算 | ★☆☆☆☆ | ★★★★★ |
Unity URP的选择在视觉质量和计算开销之间取得了最佳平衡,特别是考虑到现代GPU的架构特性(SIMD执行),即使包含sqrt运算也不会造成显著性能瓶颈。
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)