Unity URP 渲染中的灯光数量设置— 场景、使用方法与渲染原理详解

Unity URP 渲染中的灯光数量设置详解

Universal Render Pipeline (URP) 是 Unity 的轻量级渲染管线,专为移动和中低端设备优化。在 URP 中,灯光数量设置直接影响场景渲染性能和视觉质量。URP 默认使用前向渲染(Forward Rendering),这会限制每个对象渲染的附加灯光数量,以避免 GPU 开销过大。以下详解灯光数量的设置场景、使用方法和渲染原理,基于 Unity 6(2025 年版本)和 URP 16.x+(兼容 Unity 2021.3+)。如果使用 Built-in RP 或 HDRP,灯光处理机制不同(HDRP 支持更多动态灯光)。

1. 灯光数量设置的场景与重要性

URP 中的灯光数量设置主要针对附加灯光(Additional Lights),即除主方向光(Main Directional Light)外的点光源(Point)、聚光源(Spot)和额外方向光(Directional)。主方向光不计入限制,通常是场景的主要光源。

适用场景:

  • 性能优化:在移动端或低端 PC 上,限制灯光数量可保持 60 FPS(如 AR/VR 项目)。
  • 质量分级:不同设备/设置(如 Low/Medium/High Quality)使用不同灯光上限,实现动态调整(e.g., 手机 4 盏,PC 16 盏)。
  • 复杂场景:室内多灯(如房间灯泡)或室外动态灯(如街灯),超出限制时灯光会按距离/重要性剔除。
  • 艺术控制:限制灯光避免过度照明,确保艺术一致性(如夜景仅 2-4 盏灯)。
  • XR 项目:头显渲染双目视图,开销翻倍,需严格限制灯光(推荐 4-8 盏)。

为什么需要设置?

  • 默认限制:URP 前向渲染每个对象最多渲染 8 盏附加灯光(Per-Object Limit),超出部分忽略(按距离排序)。
  • 性能影响:每盏灯增加 Draw Call 和像素计算,过多导致掉帧(e.g., 16 盏灯 vs 8 盏,GPU 负载 +50%)。
  • 平衡:更多灯光需切换 Deferred Rendering,但 Deferred 在低端设备上更慢(内存开销高)。

2. 使用方法:如何设置灯光数量

URP 灯光设置集中在 URP Asset(渲染资产)中,可为不同质量级别创建多个 Asset。步骤如下:

步骤1: 创建/编辑 URP Asset

  • Edit > Project Settings > Graphics > Scriptable Render Pipeline Settings > 创建/选择 URP Asset(如果无,Assets > Create > Rendering > URP Asset)。
  • Inspector 中展开 Lighting 部分:
  • Main Light:主方向光设置(不限数量,通常 1 盏)。
  • Additional Lights
    • Cast Shadows:附加灯光是否投射阴影(影响性能)。
    • Per-Object Limit:每个对象渲染的附加灯光上限(默认 8,范围 1-32;低端设 4,中端 8,高端 16+)。
    • Light Cookie:附加灯光纹理支持(可选)。

步骤2: 质量分级配置

  • Edit > Project Settings > Quality > Quality Levels > 创建多个级别(e.g., Low/Medium/High)。
  • 每个级别关联不同 URP Asset:
  • Low: Per-Object Limit = 4(移动端)。
  • High: Per-Object Limit = 16(PC)。
  • 运行时切换:QualitySettings.SetQualityLevel(1);(0=Low, 1=Medium 等)。

步骤3: 切换渲染路径(更多灯光)

  • URP Asset > Rendering > Rendering Path:
  • Forward(默认):高效,但 Per-Object Limit 严格(8 盏)。
  • Deferred:支持更多灯光(理论无限,但每盏灯开销更高),适合复杂照明场景。
  • 切换 Deferred 后,灯光数量无硬限,但需监控性能(Profiler > Rendering)。

步骤4: 代码动态控制

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class DynamicLightController : MonoBehaviour
{
    public UniversalRenderPipelineAsset urpAsset;  // 拖拽你的 URP Asset

    void Start()
    {
        // 动态设置灯光数量
        SetLightLimit(12);  // 例如 High Quality 设为 12

        // 切换渲染路径
        SetRenderingPath(RenderingPath.Deferred);
    }

    public void SetLightLimit(int limit)
    {
        if (urpAsset != null)
        {
            urpAsset.maxAdditionalLightsCount = Mathf.Clamp(limit, 1, 32);  // 附加灯光上限
            GraphicsSettings.renderPipelineAsset = urpAsset;  // 应用变更
        }
    }

    public void SetRenderingPath(RenderingPath path)
    {
        if (urpAsset != null)
        {
            urpAsset.renderingPath = path;
            GraphicsSettings.renderPipelineAsset = urpAsset;
        }
    }

    // 示例:根据设备性能调整
    public void AdjustForDevice()
    {
        int limit = SystemInfo.processorCount > 4 ? 16 : 8;  // 高端设备更多灯光
        SetLightLimit(limit);
    }
}
  • 注意:动态变更需在运行时应用;编辑器中直接修改 Asset。

步骤5: 场景灯光测试

  • 添加多个 Point Lights(>8 盏)。
  • 运行 Play Mode,观察剔除(最近灯光优先)。
  • Profiler > Rendering > Lights:查看实际渲染灯光数。

3. 渲染原理详解

URP 灯光渲染基于 Scriptable Render Pipeline (SRP),优化为前向/延迟两种路径。

前向渲染(Forward Rendering,默认)

  • 原理
  • 每个对象渲染时计算所有影响灯光(逐像素光照)。
  • Per-Object Limit:每个对象仅渲染最近/最重要的 N 盏附加灯光(N=8 默认),超出忽略(按距离/强度排序)。
  • 主方向光(Directional Light)不限,始终渲染(全局影响)。
  • 性能:高效,低内存,但灯光数受限(避免昂贵的多光源着色)。
  • 计算流程
    1. 场景剔除(Culling):确定可见对象。
    2. 灯光排序:按距离/重要性排序附加灯光。
    3. 渲染 Pass:对象 Draw 时仅应用前 N 盏灯的贡献(Shader 中累加)。
  • 缺点:复杂场景(如 20+ 灯)会丢失远处灯光效果。

延迟渲染(Deferred Rendering,可切换)

  • 原理
  • 先渲染 G-Buffer(几何缓冲:颜色/法线/深度等)。
  • 后处理 Pass 中统一计算所有灯光(逐像素光照)。
  • 灯光数量:理论无限(受 GPU 内存限),每盏灯独立 Pass(开销随灯光数线性增长)。
  • 支持更多灯光(e.g., 32+ 盏),适合室内多光源。
  • 性能:高内存开销,低端设备(如手机)不推荐;启用后 Per-Object Limit 无效。
  • 计算流程
    1. Geometry Pass:填充 G-Buffer。
    2. Lighting Pass:遍历所有灯光,累加贡献。
    3. Final Pass:合成图像。
  • 缺点:不支持 MSAA(抗锯齿),需 TAA 替代;移动端热量/功耗高。

全局 vs 附加灯光

  • Main Light:始终 1 盏(Directional),全局影响,不计入限制,支持阴影。
  • Additional Lights:点/聚光/额外方向光,受 Per-Object Limit 限制,支持 Cookie(纹理投影)。
  • 实时 vs 烘焙:实时灯光动态计算,烘焙灯光预计算(Lightmap),不计入限制,但静态。

渲染数据流

  • URP ForwardRenderer:Clustered Lighting(聚类灯光),高效剔除远处灯。
  • Shader 变体:URP 自动生成变体,根据灯光数优化(e.g., #pragma multi_compile _ _ADDITIONAL_LIGHTS)。
  • 空间音频影响:灯光计算支持 AudioListener 位置,实现 3D 声音同步。

性能测试与优化

  • 测试方法:Profiler > Rendering > Lights > 查看 Draw Calls 和 Batch。
  • 优化技巧
  • 减少实时灯:使用 Light Probes/Baked GI 替换静态灯。
  • Cookie/Shadows:仅关键灯启用(开销高)。
  • LOD:远距离灯使用低强度/简化 Shader。
  • Mobile:限制 4-6 盏灯,禁用 Shadows。
  • 基准:1080p 场景,8 盏灯 ~200 Draw Calls(GTX 1660);Deferred 16 盏 ~300 Calls。

总结与注意事项

  • 总结:URP 灯光数量通过 URP Asset 配置,Forward 限 8 盏/对象,Deferred 支持更多。动态代码控制灵活,适合质量分级。
  • 注意
  • 兼容:URP 16.x+ 支持更多自定义(e.g., Light Layers)。
  • XR:双目渲染开销翻倍,建议 4 盏灯。
  • 升级:从 Built-in 迁移需 Upgrade Materials。
  • 文档:Unity Manual > URP > Lighting(官方详解)。

如果需要代码示例或 Deferred 配置细节,请提供更多信息!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注