版本:Unity 6 (6000.0)
语言:英语
升级 URP
升级到 URP 16(Unity 2023.2)

升级到 URP 17(Unity 6)

此页面介绍如何从旧版本的通用渲染管线一系列将场景内容显示到屏幕上的操作。Unity 允许您选择预构建的渲染管线,或编写自己的渲染管线。 更多信息
参见 术语表
(URP) 升级到 URP 17(Unity 6)。

有关将为内置渲染管线项目制作的资源转换为与 URP 兼容的资源的信息,请参阅页面 渲染管线转换器

从 URP 15 或 URP 16(Unity 2023.1、Unity 2023.2)升级

渲染图系统

URP 17 引入了 渲染图 系统,其中包括对编写自定义渲染通道方式的重大更改。

如果您的项目包含自定义渲染通道,请使用渲染图 API 重写您的通道。有关渲染图的更多信息,请参阅部分 渲染图系统

以下页面包含一个完整的可脚本化渲染功能示例,其中包含使用渲染图 API 的渲染通道

注意:Unity 不再开发或改进不使用 渲染图 API渲染路径渲染管线用于渲染图形的技术。选择不同的渲染路径会影响灯光和阴影的计算方式。某些渲染路径比其他渲染路径更适合不同的平台和硬件。 更多信息
参见 术语表

渲染图在新的 URP 项目中默认启用。

出于兼容性目的,Unity 6 包括禁用渲染图系统并使用先前 URP 版本的渲染 API 的选项。要禁用渲染图,请启用以下复选框

  • 项目设置 > 图形 > 渲染图 > 兼容模式(渲染图已禁用)

如果您打开使用没有渲染图的 URP 版本创建的现有项目,Unity 会在使用 Unity 6 打开项目后自动启用兼容模式。

要更好地理解渲染图实现,请使用 渲染图查看器

体积框架

当您创建覆盖 VolumeComponent.Override(VolumeComponent state, float interpFactor) 方法的自定义体积组件类时,您的实现必须在每次更改 VolumeParameter 值时将 VolumeParameter.overrideState 属性设置为 true。这可确保体积框架将参数重置为其正确的默认值。这允许框架在每一帧中使用更少的资源,从而提高性能。

从 URP 13(Unity 2022.1)升级

删除了两个着色器定义

SHADER_QUALITY_LOW/MEDIUM/HIGHSHADER_HINT_NICE_QUALITY 着色器在 GPU 上运行的程序。 更多信息
参见 术语表
定义已被删除。如果您在自定义着色器中使用了这些定义,请考虑使用 SHADER_API_MOBILESHADER_API_GLES 定义来替换 SHADER_QUALITY_LOW/MEDIUM/HIGH

从 URP 12(Unity 2021.2)升级

可脚本化渲染器 API 行为的更改

ScriptableRendererFeature 的实例尝试在 ScriptableRenderer 类分配之前访问渲染目标时,Unity 现在会发出错误。

ScriptableRendererFeature 类具有一个新的虚拟函数 SetupRenderPasses,该函数在分配渲染目标并准备使用时被调用。

如果您的代码在 AddRenderPasses 方法覆盖中使用 ScriptableRenderer.cameraColorTargetScriptableRenderer.cameraDepthTarget 属性,则应将该实现移动到 ScriptableRendererFeature.SetupRenderPasses 方法。

ScriptableRenderer.EnqueuePass 方法的调用仍应发生在 AddRenderPasses 方法中。

以下示例显示了如何更改代码以使用新的 API。

使用旧 API 的代码

public override void AddRenderPasses(ScriptableRenderer renderer,
                                    ref RenderingData renderingData)
{
    // The target is used before allocation
    m_CustomPass.Setup(renderer.cameraColorTarget);
     // Letting the renderer know which passes are used before allocation
    renderer.EnqueuePass(m_ScriptablePass);
}

使用新 API 的代码

public override void AddRenderPasses(ScriptableRenderer renderer,
                                        ref RenderingData renderingData)
{
    // Letting the renderer know which passes are used before allocation
    renderer.EnqueuePass(m_ScriptablePass);
}

public override void SetupRenderPasses(ScriptableRenderer renderer,
                                          in RenderingData renderingData)
{
    // The target is used after allocation
    m_CustomPass.Setup(renderer.cameraColorTarget);
}

通用渲染器现在正在使用 RTHandle 系统

通用渲染器现在正在使用 RTHandle 系统 用于其内部目标及其内部通道。

所有 RenderTargetHandle 结构的使用都已设置为已弃用,并且该结构将在将来删除。

公共接口 ScriptableRenderer.cameraColorTargetScriptableRenderer.cameraDepthTarget 已标记为已弃用。分别用 ScriptableRenderer.cameraColorTargetHandleScriptableRenderer.cameraDepthTargetHandle 替换它们。

RTHandle 目标不使用 CommandBuffer.GetTemporaryRT 方法,并且比 RenderTargetIdentifier 结构持续更多帧。您不能将 GraphicsFormatDepthBufferBits 属性设置为除 0 之外的任何值来分配 RTHandle 目标。cameraDepthTarget 属性必须与 cameraColorTarget 属性分开。

以下辅助函数允许您以类似于以前使用 GetTemporaryRT 方法的方式创建和使用带有 RTHandle 系统的临时渲染目标

  • RenderingUtils.ReAllocateIfNeeded

  • ShadowUtils.ShadowRTReAllocateIfNeeded

如果渲染目标在应用程序的生命周期内不发生变化,请使用 RTHandles.Alloc 方法分配 RTHandle 目标。此方法效率很高,因为代码不必在每一帧检查是否应分配渲染目标。

如果渲染目标是全屏纹理,这意味着其分辨率与屏幕分辨率匹配或为屏幕分辨率的一部分,请使用缩放因子(如 Vector2D.one)来支持动态缩放。

以下示例显示了如何更改使用 RenderTargetHandle API 的代码以使用新的 API。

使用旧 API 的代码

public class CustomPass : ScriptableRenderPass
{
    RenderTargetHandle m_Handle;
    // With the old API, RenderTargetIdentifier might combine color and depth
    RenderTargetIdentifier m_Destination;

    public CustomPass()
    {
        m_Handle.Init("_CustomPassHandle");
    }

    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
        var desc = renderingData.cameraData.cameraTargetDescriptor;
        cmd.GetTemporaryRT(m_Handle.id, desc, FilterMode.Point);
    }

    public override void OnCameraCleanup(CommandBuffer cmd)
    {
        cmd.ReleaseTemporaryRT(m_Handle.id);
    }

    public void Setup(RenderTargetIdentifier destination)
    {
        m_Destination = destination;
    }

    public override void Execute(ScriptableRenderContext context,
                                    ref RenderingData renderingData)
    {
        CommandBuffer cmd = CommandBufferPool.Get();
        // Set the same target for color and depth
        ScriptableRenderer.SetRenderTarget(cmd, m_Destination, m_Destination, clearFlag,
                                              clearColor);
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }
}

使用新 API 的代码

public class CustomPass : ScriptableRenderPass
{
    RTHandle m_Handle;
    // Then using RTHandles, the color and the depth properties must be separate
    RTHandle m_DestinationColor;
    RTHandle m_DestinationDepth;

    void Dispose()
    {
        m_Handle?.Release();
    }

    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
        var desc = renderingData.cameraData.cameraTargetDescriptor;
        // Then using RTHandles, the color and the depth properties must be separate
        desc.depthBufferBits = 0;
        RenderingUtils.ReAllocateIfNeeded(ref m_Handle, desc, FilterMode.Point,
                                         TextureWrapMode.Clamp, name: "_CustomPassHandle");
    }

    public override void OnCameraCleanup(CommandBuffer cmd)
    {
        m_DestinationColor = null;
        m_DestinationDepth = null;
    }

    public void Setup(RTHandle destinationColor, RTHandle destinationDepth)
    {
        m_DestinationColor = destinationColor;
        m_DestinationDepth = destinationDepth;
    }

    public override void Execute(ScriptableRenderContext context,
                                    ref RenderingData renderingData)
    {
        CommandBuffer cmd = CommandBufferPool.Get();
        ScriptableRenderer.SetRenderTarget(cmd, m_DestinationColor, m_DestinationDepth,
                                              clearFlag, clearColor);
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }
}

从 URP 11.x.x 升级

  • 前向渲染器资源已重命名为通用渲染器资源。当您在 Unity 编辑器中打开包含 URP 12 的现有项目时,Unity 会将现有前向渲染器资源更新为通用渲染器资源。

  • 通用渲染器资源包含允许您选择前向或延迟渲染路径的属性渲染路径

  • 方法 ClearFlag.Depth 不再隐式清除模板缓冲区存储每个像素 8 位值的内存存储。在 Unity 中,您可以使用模板缓冲区标记像素,然后仅渲染通过模板操作的像素。 更多信息
    参见 术语表
    。使用新方法 ClearFlag.Stencil

  • URP 12 及更高版本实现了 渲染管线转换器 功能。此功能替换了以前在编辑 > 渲染管线 > 通用渲染管线 > 升级…中可用的资源升级功能。

从 URP 10.0.x–10.2.x 升级

  1. 以下着色器图着色器的文件名已重命名。新文件名不包含空格
    Autodesk Interactive
    Autodesk Interactive Masked
    Autodesk Interactive Transparent

    如果您的代码使用 Shader.Find() 方法搜索着色器,请从着色器名称中删除空格,例如 Shader.Find("AutodeskInteractive)

从 URP 7.2.x 及更高版本升级

  1. URP 12.x.x 不支持包后期处理在图像显示在屏幕上之前应用滤镜和效果来改善产品视觉效果的过程。您可以使用后期处理效果模拟物理相机和胶片属性,例如 Bloom 和景深。 更多信息 post processing, postprocessing, postprocess
    参见 术语表
    堆栈 v2。如果您的项目使用包后期处理堆栈 v2,请首先迁移使用该包的效果。

深度法线通道

从 10.0.x 版本开始,URP 可以生成名为 _CameraNormalsTexture 的法线纹理。要在自定义着色器中渲染到此纹理,请添加名称为 DepthNormals 的通道。有关示例,请检查 Lit.shader 中的实现。

屏幕空间环境光遮蔽 (SSAO)

URP 10.0.x 实现了屏幕空间环境光遮蔽一种近似计算表面上一点可以接收多少环境光(非来自特定方向的光)的方法。
参见 术语表
(SSAO) 效果。

如果您打算在自定义着色器中使用 SSAO 效果,请考虑以下与 SSAO 相关的实体

  • _SCREEN_SPACE_OCCLUSION 关键字。

  • Input.hlslInputData 结构中包含新的声明 float2 normalizedScreenSpaceUV

  • Lighting.hlsl 包含用于计算间接和直接遮挡的变量的 AmbientOcclusionFactor 结构

    struct AmbientOcclusionFactor
    {
        half indirectAmbientOcclusion;
        half directAmbientOcclusion;
    };
    
  • Lighting.hlsl 包含以下用于采样 SSAO 纹理的函数

    half SampleAmbientOcclusion(float2 normalizedScreenSpaceUV)
    
  • Lighting.hlsl 包含以下函数

    AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2
    normalizedScreenSpaceUV)
    

要支持自定义着色器中的 SSAO,请将 DepthNormals 通道和 _SCREEN_SPACE_OCCLUSION 关键字添加到着色器中。有关示例,请检查 Lit.shader

如果您的自定义着色器实现了自定义灯光功能,请使用函数 GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV) 获取灯光计算的 AmbientOcclusionFactor 值。

阴影法线偏差

在 11.0.x 中,用于应用阴影法线偏差的公式已略微修复,以便更好地与点光源配合使用。因此,为了完全匹配早期版本的阴影轮廓,可能需要在某些场景场景包含游戏的环境和菜单。可以将每个唯一的场景文件视为唯一的关卡。在每个场景中,您放置环境、障碍物和装饰,从本质上讲是分段设计和构建您的游戏。 更多信息
参见 术语表
中调整参数。通常,对于方向光使用 1.4 而不是 1.0 通常就足够了。

中间纹理

在以前的 URP 版本中,如果渲染器有任何活动的渲染器功能,URP 将通过中间渲染器执行渲染。在某些平台上,这会带来重大的性能影响。在此版本中,URP 通过以下方式缓解了此问题:URP 预期渲染器功能使用 ScriptableRenderPass.ConfigureInput 方法声明其输入。该方法提供 URP 用于自动确定是否需要通过中间纹理进行渲染的信息。

为了兼容性,通用渲染器中新增了一个属性**中间纹理**。如果在该属性中选择**始终**,URP 将使用中间纹理。选择**自动**将启用新行为。仅当渲染器功能未使用ScriptableRenderPass.ConfigureInput方法声明其输入时,才使用**始终**选项。

为了确保现有项目正常工作,所有使用任何渲染器功能(不包括URP自带的功能)的现有通用渲染器资源在**中间纹理**属性中都选择了**始终**选项。任何新创建的通用渲染器资源都选择了**自动**选项。

从URP 7.0.x–7.1.x升级

  1. 首先升级到URP 7.2.0。请参考升级到通用渲染管线 7.2.0 版本

  2. URP 8.x.x 不支持包 后处理堆栈 v2。如果您的项目使用包 后处理堆栈 v2,请先迁移使用该包的效果。

从LWRP升级到12.x.x

  • 从LWRP到URP 12.x.x没有直接的升级路径。请先按照步骤将LWRP升级到URP 11.x.x,然后再从URP 11.x.x升级到URP 12.x.x。
升级 URP
升级到 URP 16(Unity 2023.2)