Stories

Detail Return Return

【光照】[PBR][鏡面反射]實現方法解析 - Stories Detail

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

微表面理論的核心概念

微表面理論是一種物理渲染模型,它將宏觀表面視為由無數微觀幾何細節(微表面)組成的複雜結構。這一理論是Unity URP中PBR(基於物理的渲染)實現的基礎。

基本假設

  • 微觀結構‌:
    • 宏觀表面由大量隨機方向的微觀小平面組成
    • 每個微表面都是完美的鏡面反射體
    • 微表面尺度小於單個像素但大於光波長
  • 宏觀表現‌:
    • 粗糙度:描述微表面法線分佈的集中程度
    • 光澤度:反射方向的集中程度
    • 菲涅爾效應:視角變化導致的反射率變化

核心方程

微表面理論的核心是Cook-Torrance BRDF方程:

$f_r=\frac{DFG}{4(ω_o⋅n)(ω_i⋅n)}$

  • 其中:
    • D:法線分佈函數(NDF)
    • F:菲涅爾方程
    • G:幾何遮蔽函數
    • $ω_i$:入射光方向
    • $ω_o$:出射光方向
    • n:表面法線

Unity URP中的微表面實現

1. 法線分佈函數(Normal Distribution Function - NDF)

作用‌:描述微表面法線朝向的概率分佈

Unity URP實現‌:Trowbridge-Reitz GGX分佈

hlsl
// 代碼路徑: Packages/com.unity.render-pipelines.universal/ShaderLibrary/BRDF.hlsl
float D_GGX(float NdotH, float roughness)
{
    float a = roughness * roughness;
    float a2 = a * a;
    float NdotH2 = NdotH * NdotH;

    float denom = NdotH2 * (a2 - 1.0) + 1.0;
    denom = PI * denom * denom;

    return a2 / max(denom, 0.000001); // 避免除零錯誤
}

數學公式‌:

$D_{GGX}(h) = \frac{\alpha_g2}{\pi[(n·h)2(\alpha_g2-1)+1]2}$

特性‌:

  • 高光區域隨粗糙度增加而擴散
  • 能量守恆,保持亮度一致
  • 長尾分佈,模擬真實表面散射

2. 幾何遮蔽函數(Geometry Function - G)

作用‌:模擬微表面間的自陰影和遮蔽效應

Unity URP實現‌:Smith聯合Schlick-GGX模型

hlsl
// 幾何遮蔽項計算
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);
}

數學公式‌:

$G(n,v,l)=G_1(n,v)⋅G_1(n,l)$

其中:

$G_1(n,v)=\frac{n⋅v}{(n⋅v)(1−k)+k},k=\frac{(α+1)}8$

特性‌:

  • 粗糙表面邊緣產生更多陰影
  • 模擬掠射角時的光線衰減
  • 保持能量守恆

3. 菲涅爾方程(Fresnel Equation - F)

作用‌:描述不同視角下的反射率變化

Unity URP實現‌:Schlick近似

hlsl
// 菲涅爾項計算
float3 F_Schlick(float cosTheta, float3 F0)
{
    return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}

數學公式‌:

$F(v,h)=F_0+(1−F_0)(1−(v⋅h))^5$

特性‌:

  • F0F0 是0度角的基礎反射率
  • 掠射角反射率接近100%
  • 金屬與非金屬材質反射特性不同

URP中的完整微表面BRDF實現

Unity URP中的鏡面反射計算在BRDF.hlsl文件中實現:

hlsl
// 完整鏡面反射BRDF計算
float3 BRDF_Specular(float3 F0, float roughness, float NdotH, float NdotL, float NdotV, float LdotH)
{
    // 1. 計算法線分佈
    float D = D_GGX(NdotH, roughness);

    // 2. 計算幾何遮蔽
    float V = V_SmithGGX(NdotL, NdotV, roughness);

    // 3. 計算菲涅爾反射
    float3 F = F_Schlick(LdotH, F0);

    // 4. 組合Cook-Torrance BRDF
    return (D * V) * F;
}

完整鏡面反射調用鏈

  • 數據準備階段‌:

    hlsl
    // 獲取光線數據
    Light light = GetMainLight();
    float3 halfVec = normalize(light.direction + viewDir);
    
    // 計算中間量
    float NdotV = saturate(dot(normalWS, viewDir));
    float NdotL = saturate(dot(normalWS, light.direction));
    float NdotH = saturate(dot(normalWS, halfVec));
    
  • BRDF計算階段‌:

    hlsl
    // 計算三項核心參數
    float D = D_GGX(NdotH, roughness);
    float G = G_Smith(NdotV, NdotL, roughness);
    float3 F = F_Schlick(max(dot(halfVec, viewDir), 0), F0);
    
    // 最終鏡面反射
    float3 specular = (D * G * F) / (4 * NdotV * NdotL + 0.0001);
    

URP 2022 LTS版本中,通過#define _SPECULARHIGHLIGHTS_OFF可關閉高光計算。實際開發時建議通過Smoothness參數(0-1範圍)控制鏡面反射強度,金屬材質會自動增強高光響應。

微表面理論與傳統模型的對比

特性 微表面模型 Phong模型 Blinn-Phong模型
物理基礎 基於物理 經驗模型 經驗模型
能量守恆
視角依賴性 精確模擬 近似 近似
材質參數 物理屬性(金屬度/粗糙度) 光澤度 光澤度
邊緣表現 精確菲涅爾 固定反射率 固定反射率
性能開銷 較高 中等

URP中的優化實現

  • 重要性採樣‌:通過預計算環境貼圖優化實時計算
  • 分割和近似‌:將環境光照分解為預過濾環境和BRDF LUT
  • 移動端優化‌:使用簡化的IBL(基於圖像的照明)計算
  • LOD控制‌:根據距離自動降低計算精度
hlsl
// 環境鏡面反射優化實現
float3 EnvBRDFApprox(float3 specColor, float roughness, float NdotV)
{
    // 使用預計算的LUT紋理
    float2 envBRDF = tex2D(_BRDFLUT, float2(NdotV, roughness)).rg;
    return specColor * envBRDF.r + envBRDF.g;
}

實際應用建議

材質設置‌:

  • 金屬度:金屬表面接近1.0,非金屬接近0.0
  • 粗糙度:光滑表面0.0-0.3,粗糙表面0.4-1.0

性能優化‌:

  • 簡單材質使用SimpleLit着色器
  • 複雜場景降低反射質量
csharp
// URP Asset中調整反射質量
UniversalRenderPipelineAsset.asset → Lighting → Reflection Quality

視覺優化‌:

  • 使用高質量法線貼圖增強微觀細節
  • 添加環境光遮蔽貼圖增強深度感

微表面理論為Unity URP提供了物理準確的渲染基礎,通過精確模擬光線與微觀表面的相互作用,實現了在各種材質和光照條件下的逼真渲染效果。


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

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

Add a new Comments

Some HTML is okay.