【光照】[PBR][几何遮蔽]实现方法对比

【从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%计算量
    • 移动端友好(无复杂数学函数)
  • ‌材质一致性 ‌:
    • 与金属/粗糙度工作流完美配合
    • 参数响应线性度好

优化技术

  • ‌预计算部分项‌:

    c 复制代码
    hlsl
    // 预计算粗糙度平方
    float a2 = roughness * roughness;
  • ‌数值稳定性处理‌:

    c 复制代码
    hlsl
    // 避免除零错误
    return 0.5 / (lambdaV + lambdaL + 1e-5f);
  • ‌移动端简化版‌:

    c 复制代码
    hlsl
    #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开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

相关推荐
Aman19844 小时前
Claude Code做Unity项目移植(二): 自动执行只读操作,告别频繁的
unity·游戏开发·vibe coding·claude code
暴走约伯13 小时前
【VFX工具链源码拆解 02】告别机械劳动(上):一键统改百个子粒子颜色与批量重命名
3d·unity·c#·材质
郝学胜-神的一滴14 小时前
游戏设计:原型与开发 18:Unity入门的第一课
人工智能·程序人生·游戏·ui·unity·游戏引擎
淡海水16 小时前
09-01-内存-Unity资源生命周期全景
unity·c#·游戏引擎·.netcore·gc
LF男男20 小时前
Flower Defense—UIFacade
unity
呆呆敲代码的小Y20 小时前
【实战精选面试题】Unity精选面试题详细解答,按模块整理汇总
人工智能·游戏·unity·游戏引擎
小贺儿开发1 天前
《流光绘忆》Unity 沉浸式光影互动
科技·unity·ai·程序员·工具·互动·光影
Aman19841 天前
Claude Code做Unity项目移植(一):从零散工具到团队式
unity·游戏开发·vibe coding·claude code·项目迁移
地狱为王1 天前
Unity使用VoxLock实现语音隔离
unity·游戏引擎·音频处理·voxlock
Jmyd01232 天前
博物馆数字展厅系统架构设计:实景采集到云渲染全链路
unity·系统架构·博物馆·数字展厅·博物馆数字化