【从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模型:
            
            
              c
              
              
            
          
          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
cShader "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
              
              
            
          
          csharp
// C#控制光源示例using UnityEngine.Rendering.Universal;
public class LightController : MonoBehaviour {
    public Light2D urpLight;
    void Update() {
        urpLight.intensity = Mathf.PingPong(Time.time, 1.5f);
    }
}
        高级配置参数:
            
            
              csharp
              
              
            
          
          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内置光照模型类型
graph TB A[URP Shader] --> B[SimpleLit] A --> C[Lit PBR] A --> D[Unlit] B --> E[Blinn-Phong变体] C --> F[GGX+Smith]
URP实现架构
graph LR A[URP Asset] --> B[ForwardRenderer] B --> C[Lighting Pass] C --> D[MainLight.hlsl] C --> E[AdditionalLights.hlsl] D --> F[Blinn-Phong计算] E --> G[逐光源叠加]
关键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))chlsl // 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开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)