【光照】Unity中的[经验模型]

【从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

    c 复制代码
    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 复制代码
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.shaderLit.shader(位于Packages/com.unity.render-pipelines.universal/Shaders/
  • 关键变量:_SpecularIntensity(控制高光强度)和_Smoothness(控制反射模糊度)

核心计算逻辑

  • Lambert漫反射 ‌:通过dot(worldNormal, worldLightDir)计算基础光照

  • Phong/Blinn-Phong镜面反射 ‌:其中halfDir为半角向量(normalize(lightDir + viewDir)

    c 复制代码
    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开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

相关推荐
山檐雾18 小时前
OctreeNode
unity·c#·八叉树
WarPigs20 小时前
Unity协程返回值的解决方案
unity·游戏引擎
WarPigs1 天前
Unity单例笔记
unity·游戏引擎
Allen74742 天前
ComfyUI 自动化生产 3D资产 工作流笔记
图像处理·opencv·unity·自然语言处理·3d模型生成·confyui
nnsix2 天前
Unity Windows11 打字中文显示不出来输入法的候选框
unity
adogai3 天前
unity mcp接入 实现一句话生成游戏!
游戏·unity·游戏引擎
mxwin3 天前
Unity Shader 逐像素光照 vs 逐顶点光照性能与画质的权衡策略
unity·游戏引擎·shader·着色器
CDN3603 天前
游戏盾导致 Unity/UE 引擎崩溃的主要原因排查?
游戏·unity·游戏引擎
mxwin3 天前
Unity URP 全局光照 (GI) 完全指南 Lightmap 采样与实时 GI(光照探针、反射探针)的 Shader 集成
unity·游戏引擎·shader·着色器
mxwin3 天前
Unity URP 溶解效果基于噪声纹理与 clip 函数实现物体渐隐渐显
unity·游戏引擎·shader