Stories

Detail Return Return

【光照】[PBR][幾何遮蔽]實現方法對比 - Stories Detail

【從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選擇‌:

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

實現代碼‌:

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%計算量
    • 移動端友好(無複雜數學函數)
  • 材質一致性‌:
    • 與金屬/粗糙度工作流完美配合
    • 參數響應線性度好

優化技術

  • 預計算部分項‌:

    hlsl
    // 預計算粗糙度平方
    float a2 = roughness * roughness;
    
  • 數值穩定性處理‌:

    hlsl
    // 避免除零錯誤
    return 0.5 / (lambdaV + lambdaL + 1e-5f);
    
  • 移動端簡化版‌:

    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開始探索遊戲渲染】專欄-直達

(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)

Add a new Comments

Some HTML is okay.