博客 / 詳情

返回

【光照】[PBR][菲涅爾]實現方法對比

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

菲涅爾效應基本流程

菲涅爾效應(F)在BRDF中描述光線在不同入射角下的反射率變化,其計算流程通常分為三個步驟:

  • 基礎反射率確定‌:0°入射角時的反射率(F₀)
  • 角度依賴計算‌:根據入射角變化調整反射率
  • 金屬/非金屬處理‌:區分導體和絕緣體的不同表現

主要菲涅爾模型實現

1. Schlick近似模型

原理‌:

  • 對完整菲涅爾方程的簡化近似
  • 使用有理函數替代複雜計算

公式‌:

$F_{Schlick}(v,h)=F_0+(1−F_0)(1−(v⋅h))^5$

特點‌:

  • 計算效率高
  • 精度足夠實時渲染使用
  • 在掠射角(90°)強制反射率為1

Unity URP實現‌:

hlsl
// Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl
half3 F_Schlick(half u, half3 F0)
{
    return F0 + (1 - F0) * pow(1 - u, 5);
}

2. 完整菲涅爾方程

原理‌:

  • 基於麥克斯韋電磁學方程
  • 考慮光的偏振特性

公式‌:

$F_{完整}=\frac12[(\frac{g−c}{g+c})^2+(\frac{c(g+c)−1}{c(g−c)+1})^2]$

其中 $c=v⋅h, g=\sqrt{n^2+c^2−1}$

特點‌:

  • 物理精確但計算複雜
  • 主要用於離線渲染

3. Spherical Gaussian近似

原理‌:

  • 用高斯函數近似菲涅爾曲線
  • 特別適合移動端

公式‌:

$F_{SG}(v,h)=F_0+(1−F_0)2^{(−5.55473(v⋅h)−6.98316)(v⋅h)}$

特點‌:

  • 無pow函數計算
  • 適合低精度硬件

Unity URP的選擇與實現

核心方案:Schlick近似 + 金屬工作流

完整實現代碼‌:

hlsl
// URP中的菲涅爾計算
half3 F_Fresnel(half3 F0, half u)
{
    half t = pow(1 - u, 5); // Schlick的(1-cosθ)^5項
    return saturate(F0 + (1 - F0) * t); // 基礎Schlick公式
}

// 實際應用時:
half3 F = F_Fresnel(F0, saturate(dot(viewDir, halfDir)));

選擇原因‌:

  • 性能與質量平衡‌:

    • 僅需1次pow運算
    • 視覺誤差小於2%,人眼難以察覺
  • 金屬/非金屬統一處理‌:

    hlsl
    // F0基礎反射率計算
    half3 F0 = lerp(0.04, albedo, metallic); // 0.04是非金屬基礎反射率
  • 能量守恆‌:

    • 保證反射光能量不超過入射光
    • 與GGX+Smith模型完美配合
  • 藝術家友好‌:

    • 通過metallic參數直觀控制
    • 反射顏色直接取自albedo貼圖

優化實現細節

  • 移動端優化版‌:

    hlsl
    half3 F_FresnelMobile(half3 F0, half u)
    {
        half t = exp2((-5.55473 * u - 6.98316) * u); // SG近似
        return saturate(F0 + (1 - F0) * t);
    }
  • 各向異性擴展‌:

    hlsl
    half3 F_Anisotropic(half3 F0, half u, half anisotropy)
    {
        half t = pow(1 - u, 5);
        return F0 + (max(1 - anisotropy, 0.1) - F0) * t;
    }
  • 多散射補償‌:

    hlsl
    half3 F_MultiScatter(half3 F0, half u, half roughness)
    {
        half3 F = F_Fresnel(F0, u);
        half3 Favg = F0 + (1 - F0) / 21; // 平均菲涅爾
        return F + (Favg - F) * roughness * 0.9;
    }

各模型性能對比

模型 指令數 特殊函數 移動端適用性 物理精度
Schlick 6-8 pow() ★★★★☆ ★★★☆☆
完整方程 20+ sqrt等 ★☆☆☆☆ ★★★★★
Spherical Gaussian 5-7 exp2() ★★★★★ ★★☆☆☆
URP實現 7-9 pow() ★★★★☆ ★★★★☆

為什麼Schlick成為行業標準

歷史驗證‌:

  • 自1994年提出以來經過大量實踐驗證
  • 被所有主流引擎採用(Unreal, Unity, Frostbite等)

硬件友好‌:

  • 現代GPU對pow函數有硬件優化
  • 不需要複雜分支判斷

參數直觀‌:

hlsl
// 基礎反射率設置示例
float3 F0 = float3(0.04, 0.04, 0.04); // 塑料
float3 F0 = float3(0.95, 0.64, 0.54); // 銅

擴展性強‌:

  • 容易與各向異性、清漆層等效果結合
  • 支持多散射補償等高級特性

Unity URP選擇Schlick近似是在實時渲染約束下做出的最優權衡,能夠在保持物理合理性的同時滿足性能要求,特別是在移動平台上表現出色。隨着硬件發展,雖然更精確的模型變得可行,但Schlick因其簡潔有效仍然是實時渲染的首選方案。


【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.