【從UnityURP開始探索遊戲渲染】專欄-直達
圖形學第一定律:“看起來對就對”
URP光照模型發展史
- 2018年:URP首次發佈(原LWRP),繼承傳統前向渲染的Blinn-Phong簡化版
- 2019年:URP 7.x引入Basic Shader的簡化光照模型
- 2020年:URP 10.x整合PBR核心(GGX+Smith)
- 2022年:URP 14.x新增Screen Space Global Illumination (SSGI)
核心原理架構
URP的經驗光照模型基於能量守恆近似和藝術家友好設計原則,通過數學簡化實現實時渲染效率。其核心公式體系包含:
光能分佈模型:
$L_o = L_d + L_s + L_a$
$L_d = k_d * (N·L) * I$
$L_s = k_s * (N·H)^n * I$
$L_a = k_a * I_a$
- $L_d$:蘭伯特漫反射(Lambert)
- $L_s$:Blinn-Phong鏡面反射
- $L_a$:環境光分量
微表面近似:
URP的SimpleLit使用改進的Blinn-Phong模型:
hlsl
float spec = pow(max(0, dot(N, H)), _Glossiness * 256);
float3 specular = _SpecColor * lightColor * spec;
實現Blinn-Phong風格的光照模型
-
使用URP標準庫Lighting.hlsl實現光照計算
-
包含完整的頂點-片段着色器結構
-
實現Blinn-Phong風格的光照模型
-
支持主方向光的漫反射+鏡面反射計算
-
SimpleLit.shader
Shader "Custom/SimpleLit" { Properties { _BaseColor("Color", Color) = (1,1,1,1) _SpecColor("Specular", Color) = (0.5,0.5,0.5) _Gloss("Glossiness", Range(0,1)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" } HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" CBUFFER_START(UnityPerMaterial) float4 _BaseColor; float4 _SpecColor; float _Gloss; CBUFFER_END struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; }; struct Varyings { float4 positionCS : SV_POSITION; float3 normalWS : TEXCOORD0; float3 viewDirWS : TEXCOORD1; }; ENDHLSL Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag Varyings vert(Attributes IN) { Varyings OUT; OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS); OUT.viewDirWS = GetWorldSpaceViewDir(TransformObjectToWorld(IN.positionOS.xyz)); return OUT; } half4 frag(Varyings IN) : SV_Target { // 標準化向量 float3 N = normalize(IN.normalWS); float3 V = normalize(IN.viewDirWS); // 獲取主光源 Light mainLight = GetMainLight(); float3 L = mainLight.direction; float3 H = normalize(L + V); // 漫反射計算 float NdotL = max(0, dot(N, L)); float3 diffuse = _BaseColor.rgb * mainLight.color * NdotL; // 鏡面反射計算 float NdotH = max(0, dot(N, H)); float spec = pow(NdotH, _Gloss * 256); float3 specular = _SpecColor.rgb * mainLight.color * spec; // 組合輸出 return half4(diffuse + specular, 1); } ENDHLSL } } }
實際應用步驟
創建材質:
- 在Project窗口右鍵 → Create → Material
- Shader選擇"Example/SimpleLit"
光源配置:
csharp
// C#控制光源示例using UnityEngine.Rendering.Universal;
public class LightController : MonoBehaviour {
public Light2D urpLight;
void Update() {
urpLight.intensity = Mathf.PingPong(Time.time, 1.5f);
}
}
高級配置參數:
csharp
// URP Asset配置路徑
Edit → Project Settings → Graphics → Scriptable Render Pipeline Settings
關鍵參數:
- Main Light Shadows
- Additional Lights Count
- Reflection Probes
性能優化建議
- 移動平台使用
SimpleLit代替Lit - 控制
Additional Lights數量(建議≤4) - 使用
Light Layers分層渲染 - 靜態物體啓用
Baked Global Illumination
最新版URP(2023.2)已支持光線追蹤擴展包,可通過Package Manager添加Ray Tracing模塊實現混合渲染管線。
核心光照模型實現類
| 類名 | 功能 |
|---|---|
UniversalForwardRenderer |
主渲染管線入口 |
Lighting.hlsl |
包含所有光照計算函數 |
BRDF.hlsl |
實現PBR核心算法 |
MainLight.hlsl |
主方向光處理 |
AdditionalLights.hlsl |
附加點光源/聚光燈 |
URP內置光照模型類型
URP實現架構
關鍵HLSL實現
URP光照計算核心代碼路徑:
Packages/com.unity.render-pipelines.universal/ShaderLibrary/
├── Lighting.hlsl # 光照入口
├── MainLight.hlsl # 主方向光處理
├── AdditionalLights.hlsl # 附加光源
└── BRDF.hlsl # PBR基礎函數
URP中快速調用標準光照模型實現
腳本位置
- URP內置的
SimpleLit.shader和Lit.shader(位於Packages/com.unity.render-pipelines.universal/Shaders/) - 關鍵變量:
_SpecularIntensity(控制高光強度)和_Smoothness(控制反射模糊度)
核心計算邏輯
-
Lambert漫反射:通過
dot(worldNormal, worldLightDir)計算基礎光照 -
Phong/Blinn-Phong鏡面反射:其中
halfDir為半角向量(normalize(lightDir + viewDir))hlsl // Phong模型 float3 specular = pow(max(0, dot(reflectDir, viewDir)), _SpecularIntensity); // Blinn-Phong模型 float3 specular = pow(max(0, dot(normal, halfDir)), _SpecularIntensity);
Lighting.hlsl直接調用以上計算公式-調用入口
- 在Shader的
SurfaceInput.hlsl中定義光照輸入結構體InputData - 通過
UniversalFragmentBlinnPhong函數處理光照,這些都定義在Lighting.hlsl中。 - 在Lighting.hlsl中有以下經驗光照的函數可直接調用
- LightingLambert
- LightingSpecular
- CalculateBlinnPhong
- UniversalFragmentBlinnPhong
【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)