【從UnityURP開始探索遊戲渲染】專欄-直達
高光反射的基本流程
經驗光照模型中的高光反射通常遵循以下流程:
- 入射光計算:確定光源方向和強度
- 視角向量計算:確定觀察者方向
- 反射向量計算:根據表面法線計算理想反射方向
- 高光強度計算:使用特定模型計算高光反射強度
- 最終合成:將高光反射與漫反射和環境光結合
主要高光反射模型及實現
Phong模型 (1975) -經驗模型
1975 裴祥風(Bui Tuong Phong)剔除了標準光照模型背後的基本理念。標準光照只關心直接光照direct light。
-
Phong模型計算高光反射:
![Phong.png]()
- 反射方向:$r=2(n·I)n-I$
- $C_{specular}=(C_{light}·M_{specular})max(0,v·r)^{M_{gloss}}$
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal)); fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);- Mgloss 材質光澤度,也稱為反光度shininess。控制高光區域亮點有多寬,Mgloss越大,亮點越小。
特點:
- 計算反射向量需要額外步驟
- 高光邊緣過渡較硬
- 計算成本中等
Unity URP應用:
- 早期移動端簡化着色器中使用
- 現在主要用於教學演示目的
Blinn-Phong模型 (1977) -經驗模型
-
Blinn提出簡單方法得出類似效果(Blinn-Phong高光反射光照)
![Blinn-Phong.png]()
- $h=\frac{(v+I)}{|v+I|}$
- $C_{specular}=(C_{light}·M_{specular})max(0,n·h)^{M_{gloss}}$
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz); fixed3 halfDir = normalize(worldLightDir + viewDir); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);- 攝像機和光源距離物體足夠遠時,可認為v和I是定值,Blinn模型會快於Phong模型。
- 當v和I不定時,Phong可能更快。
特點:
- 比Phong模型計算效率更高
- 高光過渡更柔和自然
- 成為遊戲行業長期標準
Unity URP選用方案:
- URP內置的SimpleLit着色器使用此模型
- 移動端默認高光方案
Ward各向異性模型 (1992)
實現原理:
$高光 = 光源強度 × 特殊BRDF × exp(-tan²θ/(α²))$
其中:
- θ:微表面法線偏差角
- α:表面粗糙度參數
特點:
- 模擬金屬/毛髮等各向異性材質
- 計算複雜度較高
- 需要切線空間信息
Unity URP應用:
- 不直接內置,需要自定義着色器
- 常用於頭髮/絲綢等特殊材質
- 實現示例:
hlsl
float3 T = i.tangent;
float3 B = cross(N, T);
float dotTH = dot(T, H);
float dotBH = dot(B, H);
float spec = exp(-2.0*(dotTH*dotTH + dotBH*dotBH)/(1.0 + dotNH));
Cook-Torrance模型 (1982)
實現原理:
$高光 = (D × F × G) / (4 × (N·V) × (N·L))$
包含三個函數:
- D (微表面分佈):Beckmann/GGX
- F (菲涅爾反射):Schlick近似
- G (幾何遮蔽):Smith函數
特點:
- 物理基礎渲染(PBR)核心模型
- 計算成本最高
- 需要更多材質參數
Unity URP選用方案:
- URP的Lit着色器使用簡化版
- 主要採用GGX分佈+Schlick菲涅爾
- 實現核心:
hlsl
float D = GGXDistribution(N, H, roughness);
float F = SchlickFresnel(dot(H, V));
float G = SmithGeometry(N, V, L, roughness);
float spec = (D * F * G) / (4 * max(dot(N,V), 0.01) * max(dot(N,L), 0.01));
Unity URP的高光實現策略
多級高光系統
URP採用分層的高光處理方案:
| 質量等級 | 使用模型 | 目標平台 | 特性 |
|---|---|---|---|
| Low | Blinn-Phong | 低端移動 | 單光源簡化 |
| Medium | 改進Blinn-Phong | 主流移動 | 多光源支持 |
| High | Cook-Torrance | PC/主機 | PBR工作流 |
| Ultra | 完整PBR | 高端設備 | 多散射支持 |
URP核心實現
Shader架構:
關鍵代碼片段:
hlsl
// URP的BRDF處理 (BRDF.hlsl)
half3 BRDF_Simple(
half3 albedo, half3 specular,
half smoothness, half3 normal,
half3 lightDir, half3 viewDir)
{
half3 halfVec = SafeNormalize(lightDir + viewDir);
half NdotH = saturate(dot(normal, halfVec));
half modifier = pow(NdotH, smoothness * smoothness * 50.0);
return specular * modifier;
}
// URP的PBR BRDF (BRDF_PBR.hlsl)
half3 BRDF_PBR(
half3 albedo, half metallic,
half smoothness, half3 normal,
half3 lightDir, half3 viewDir)
{
half perceptualRoughness = 1.0 - smoothness;
half roughness = perceptualRoughness * perceptualRoughness;
half3 halfVec = SafeNormalize(lightDir + viewDir);
half NdotV = saturate(dot(normal, viewDir));
half NdotL = saturate(dot(normal, lightDir));
// GGX分佈
half D = DistributionGGX(normal, halfVec, roughness);
// 菲涅爾Schlick近似
half3 F = FresnelSchlick(halfVec, viewDir, metallic);
// 幾何遮蔽
half G = GeometrySmith(normal, viewDir, lightDir, roughness);
return (D * F * G) / (4.0 * NdotV * NdotL + 0.0001);
}
移動端優化技巧
- 近似計算:
- 使用半精度浮點(half)
- 預計算菲涅爾項
- 簡化幾何函數
- 紋理烘焙:
- 粗糙度映射使用LUT
- 環境反射使用立方體貼圖
- 着色頻率控制:
- 頂點着色器計算低頻高光
- 像素着色器處理細節
方案選型原因分析
為什麼URP選擇混合方案?
- 性能與質量平衡:
- 低端設備:Blinn-Phong (60%性能提升)
- 高端設備:PBR (100%物理準確)
- 美術工作流統一:
- 統一的光滑度參數(0-1)
- 自動模型切換無感知
- 平台適應性:
- 根據GPU能力動態調整
- 保留核心視覺一致性
技術對比數據
| 模型 | 計算週期 | 內存訪問 | 視覺保真度 |
|---|---|---|---|
| Phong | 18 | 5 | 70% |
| Blinn-Phong | 15 | 4 | 75% |
| Cook-Torrance | 35 | 8 | 95% |
| URP優化版 | 22 | 6 | 88% |
實際項目建議
-
移動遊戲:
hlsl // 使用SimpleLit着色器 Shader "Universal Render Pipeline/Simple Lit" -
AAA級項目:
hlsl // 使用完整PBR管線 Shader "Universal Render Pipeline/Lit" -
風格化渲染:
hlsl // 自定義高光形狀 float spec = pow(dotNH, _Glossiness) * step(0.9, dotNH);
Unity URP的高光反射實現體現了現代渲染引擎的設計哲學:在物理精確性與實時性能之間尋找最佳平衡點,通過分層架構滿足不同項目需求,同時保持美術工作流的一致性。這種靈活而高效的設計使URP成為跨平台開發的理想選擇。
【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)

