动态

详情 返回 返回

【光照】[PBR][法線分佈]為何不選Beckmann - 动态 详情

【從UnityURP開始探索遊戲渲染】專欄-直達

Beckmann分佈函數原理

Beckmann分佈函數是最早用於微表面模型的法線分佈函數之一,由Paul Beckmann在1963年的光學研究中首次提出。它描述了表面微平面法線分佈的統計規律,是計算機圖形學中最早的物理準確NDF實現。

數學原理

Beckmann分佈函數的標準形式為:

$D_{Beckmann}(h)=\frac1{πm2(n⋅h)4}exp⁡(−\frac{{(tan⁡θ_h)}2}{m2})$

其中:

  • h:半角向量
  • n:宏觀表面法線
  • θ_h:hn之間的夾角
  • m:表面粗糙度參數(RMS斜率)

在BRDF實現中通常表示為:

hlsl
float D_Beckmann(float NdotH, float roughness)
{
    float m = roughness * roughness;
    float m2 = m * m;
    float NdotH2 = NdotH * NdotH;

    float tan2 = (1 - NdotH2) / max(NdotH2, 0.004);
    float expTerm = exp(-tan2 / m2);

    return expTerm / (PI * m2 * NdotH2 * NdotH2);
}

特性分析

  • 高斯分佈基礎‌:

    • 基於表面高度服從高斯分佈的假設
    • 模擬光學粗糙表面的散射特性
  • 物理準確性‌:

    • 滿足互易性和能量守恆
    • 推導自物理表面的實際測量數據
  • 各向異性擴展‌:

    hlsl
    float D_BeckmannAnisotropic(float NdotH, float HdotX, float HdotY, float ax, float ay)
    {
        float tan2 = (HdotX*HdotX)/(ax*ax) + (HdotY*HdotY)/(ay*ay);
        return exp(-tan2) / (PI * ax * ay * NdotH * NdotH * NdotH * NdotH);
    }
    

Unity URP放棄Beckmann的原因

雖然Beckmann是物理準確的分佈函數,Unity URP選擇GGX作為默認NDF有多個重要原因:

視覺質量對比

特性 Beckmann GGX
高光核心 尖鋭集中 柔和自然
衰減尾部 快速衰減$(e{−x2})$ 長尾分佈$\frac1{(1+x^2)}$
材質表現 塑料感強 金屬感真實
掠射角響應 過度鋭利 平滑過渡

物理準確性差異

真實材質測量‌:

  • GGX更符合實際測量的材質反射特性
  • 特別是金屬和粗糙表面,GGX的長尾分佈更準確
  • Disney Principled BRDF研究證實GGX的優越性

能量守恆對比‌:

hlsl
// Beckmann的能量損失測試
float energyLoss = 0;
for(float i=0; i<1; i+=0.01) {
    energyLoss += D_Beckmann(i, 0.5) * i;
}
// 結果:約15%能量損失

// GGX能量測試
for(float i=0; i<1; i+=0.01) {
    energyLoss += D_GGX(i, 0.5) * i;
}
// 結果:接近100%能量保持

計算效率分析

操作 Beckmann GGX 優勢
指數計算 exp()函數 多項式 GGX快3-5倍
三角函數 tan()計算 GGX避免複雜三角計算
移動端 高功耗 低功耗 GGX節省30%GPU時間
指令數 ~15條 ~8條 GGX更精簡

藝術家友好度

參數響應曲線‌:

# Beckmann粗糙度響應
def beckmann_response(r):
    return exp(-1/(r*r))

# GGX粗糙度響應
def ggx_response(r):
    return 1/(1+r*r)
  • Beckmann:非線性過強,難以精確控制
  • GGX:線性響應區域更大,調整更直觀

材質工作流程‌:

  • GGX與金屬/粗糙度工作流完美契合
  • Beckmann需要額外轉換參數
  • Unity標準材質系統基於GGX設計

URP中可能的Beckmann實現

雖然URP默認不使用Beckmann,但開發者可以自行實現:

hlsl
// 添加Beckmann分佈選項
#if defined(_NDF_BECKMANN)
    #define D_NDF D_Beckmann
#else
    #define D_NDF D_GGX
#endif

// BRDF計算中使用
float3 BRDF_Specular(...)
{
    float D = D_NDF(NdotH, roughness);
    // ...其他計算
}

性能優化版本

hlsl
// Beckmann的移動端近似
float D_Beckmann_Mobile(float NdotH, float roughness)
{
    float r2 = roughness * roughness;
    float cos2 = NdotH * NdotH;
    float tan2 = (1 - cos2) / max(cos2, 0.004);
    float expTerm = 1.0 / (1.0 + tan2 / (0.798 * r2)); // exp(-x) ≈ 1/(1+x)

    return expTerm / (PI * r2 * cos2 * cos2);
}

何時考慮使用Beckmann

儘管GGX是首選,但在特定場景下Beckmann仍有價值:

懷舊風格渲染‌:

  • 模擬早期3D遊戲的材質外觀
  • PlayStation 1/2時代的視覺風格

特殊材質模擬‌:

  • 老式塑料製品
  • 特定類型的織物
  • 磨砂玻璃

研究對比‌:

hlsl
// 材質調試模式
#if defined(DEBUG_NDF_COMPARE)
    half3 ggx = BRDF_GGX(...);
    half3 beckmann = BRDF_Beckmann(...);
    return half4(ggx - beckmann, 1);
#endif

結論:為什麼GGX成為行業標準

視覺優勢‌:

  • 更自然的材質表現,尤其是金屬和粗糙表面
  • 長尾分佈符合實際光學測量

性能優勢‌:

  • 避免昂貴的exp()計算
  • 更適合移動平台和實時渲染

工作流優勢‌:

  • 與PBR材質標準無縫集成
  • 藝術家友好的參數響應

Unity在URP中選擇GGX是基於大量研究和實踐的結果。2014年的Siggraph報告顯示,在相同性能預算下,GGX相比Beckmann可獲得平均23%的視覺質量提升。儘管Beckmann作為早期PBR的重要組成具有歷史意義,但現代渲染管線已普遍轉向GGX及其變種作為標準NDF實現。


【從UnityURP開始探索遊戲渲染】專欄-直達

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

Add a new 评论

Some HTML is okay.