版本:Unity 6 (6000.0)
语言:英语
URP 中兼容模式下完整可脚本化渲染器功能的示例
URP 的可脚本化渲染通道兼容模式 API 参考

在 URP 的兼容模式下执行全屏 Blit 的示例

此页面上的示例描述了如何创建一个自定义渲染器功能,该功能执行全屏 blit“位块传输”的简称。Blit 操作是将内存中的一块数据传输到另一块内存的过程。
请参阅 术语表
.

注意:Unity 不再开发或改进不使用 渲染图 API 的渲染路径。在开发新的图形功能时,请使用渲染图 API。要使用此页面上的说明,请在 URP 图形设置中启用兼容模式(渲染图禁用)项目设置 > 图形)。

示例概述

此示例实现了以下解决方案

  • 一个 自定义渲染器功能 调用一个自定义 渲染通道.

  • 渲染通道 将不透明纹理 Blit 到当前渲染器的 相机颜色目标。渲染通道使用命令缓冲区为两只眼睛绘制全屏 网格Unity 中的主要图形基元。网格构成了 3D 世界的很大一部分。Unity 支持三角形或四边形多边形网格。Nurbs、Nurms、Subdiv 表面必须转换为多边形。 更多信息
    请参阅 术语表
    .

该示例包括 着色器,它执行渲染的 GPU 侧。该 着色器在 GPU 上运行的程序。 更多信息
请参阅 术语表
使用 XR一个涵盖虚拟现实 (VR)、增强现实 (AR) 和混合现实 (MR) 应用程序的总称。支持这些形式的交互式应用程序的设备被称为 XR 设备。 更多信息
请参阅 术语表
采样器宏对颜色缓冲区进行采样。

先决条件

此示例需要以下内容

  • 可脚本化渲染管线设置属性指的是 URP 资源(项目设置 > 图形 > 可脚本化渲染管线设置)。

创建示例场景和游戏对象

要遵循此示例中的步骤,请创建一个包含以下 游戏对象Unity 场景中的基本对象,可以代表角色、道具、场景、相机、航路点等。游戏对象的功能由附加到它的组件定义。 更多信息
请参阅 术语表
的新 场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,您放置环境、障碍物和装饰,本质上是分块设计和构建您的游戏。 更多信息
请参阅 术语表

  1. 创建一个立方体。确保立方体从主 相机一个组件,它在场景中创建特定视角的图像。输出要么绘制到屏幕上,要么捕获为纹理。 更多信息
    请参阅 术语表
    中清晰可见。

现在您拥有遵循此示例中步骤所需的场景。

示例实现

本节假设您已创建了如 创建示例场景和游戏对象 一节中所述的场景。

请遵循以下步骤创建一个具有自定义 渲染通道自定义渲染器功能

  1. 创建一个新的 C# 脚本。将其命名为ColorBlitRendererFeature.cs。此脚本实现自定义渲染器功能。

    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;
    
    internal class ColorBlitRendererFeature : ScriptableRendererFeature
    {
        public Shader shader;
        [Range(0f, 1f)] public float intensity = 1f;
    
        Material m_Material;
        ColorBlitPass m_RenderPass;
    
        // Use this method to add one or more Render Passes into the rendering sequence of the renderer with the EnqueuePass method.
        public override void AddRenderPasses(ScriptableRenderer renderer,
            ref RenderingData renderingData)
        {
            if (m_Material == null)
                return;
                
            if (renderingData.cameraData.cameraType != CameraType.Game)
                return;
                
            m_RenderPass.SetIntensity(intensity);
            renderer.EnqueuePass(m_RenderPass);
        }
    
        // Use the Create method to initialize the resources. This method only runs in the first frame.
        // Use the Dispose method to clean up the resources before the renderer feature is disabled.
        public override void Create()
        {
            m_Material = CoreUtils.CreateEngineMaterial(shader);
            m_RenderPass = new ColorBlitPass(m_Material);
        }
    
        protected override void Dispose(bool disposing)
        {
            CoreUtils.Destroy(m_Material);
        }
    }
    
  2. 创建一个新的 C# 脚本。将其命名为ColorBlitPass.cs。此脚本实现执行自定义 Blit 绘制调用的自定义渲染通道。

    此渲染通道使用 AddBlitPass 执行 Blit 操作。

    注意:不要在 URP XR 项目中使用cmd.Blit 方法,因为该方法与 URP XR 集成存在兼容性问题。使用cmd.Blit 可能会隐式启用或禁用 XR 着色器关键字,从而破坏 XR SPI 渲染。

    using UnityEngine;
    using UnityEngine.Rendering.RenderGraphModule;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;
    using UnityEngine.Rendering.RenderGraphModule.Util;
    
    public class ColorBlitPass : ScriptableRenderPass
    {
        private const string k_PassName = "ColorBlitPass";
        private Material m_Material;
        private float m_Intensity;
        private static readonly int k_IntensityID = Shader.PropertyToID("_Intensity");
    
        public ColorBlitPass(Material mat)
        {
            m_Material = mat;
            renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
        }
            
        public void SetIntensity(float intensity)
        {
            m_Intensity = intensity;
        }
    
        // Use the RecordRenderGraph method to configure the input and output parameters for the AddBlitPass method and execute the AddBlitPass method.
        public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
        {
            var resourceData = frameData.Get<UniversalResourceData>();
    
            // The following line ensures that the render pass doesn't blit
            // from the back buffer.
            if (resourceData.isActiveTargetBackBuffer)
            {
                Debug.LogError($"Skipping render pass. ColorBlitRendererFeature requires an intermediate ColorTexture, we can't use the BackBuffer as a texture input.");
                return;
            }
    
            var source = resourceData.activeColorTexture;
    
            // Define the texture descriptor for creating the destination render graph texture.
            var destinationDesc = renderGraph.GetTextureDesc(source);
            destinationDesc.name = $"CameraColor-{k_PassName}";
            destinationDesc.clearBuffer = false;
            destinationDesc.depthBufferBits = 0;
    
            // Create the texture.
            TextureHandle destination = renderGraph.CreateTexture(destinationDesc);
    
             // The AddBlitPass method adds the render graph pass that blits from the source to the destination texture.
            RenderGraphUtils.BlitMaterialParameters para = new(source, destination, m_Material, 0);
            para.material.SetFloat(k_IntensityID, m_Intensity);
            renderGraph.AddBlitPass(para, passName: k_PassName);
    
            // Use the destination texture as the camera texture to avoid the extra blit from the destination texture back to the camera texture.
            resourceData.cameraColor = destination;
        }
    }
    
  3. 创建执行 Blit 操作的着色器。将着色器文件命名为ColorBlit.shader。顶点函数输出全屏四边形位置。片段函数对颜色缓冲区进行采样,并将color * float4(0, _Intensity, 0, 1) 值返回到渲染目标。

    Shader "ColorBlit"
    {
        SubShader
        {
            Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
            ZWrite Off Cull Off
            Pass
            {
                Name "ColorBlitPass"
    
                HLSLPROGRAM
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
                #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
    
                #pragma vertex Vert
                #pragma fragment Frag
    
                float _Intensity;
    
                float4 Frag(Varyings input) : SV_Target
                {
                    // This function handles the different ways XR platforms handle texture arrays.
                    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
    
                    // Sample the texture using the SAMPLE_TEXTURE2D_X_LOD function
                    float2 uv = input.texcoord.xy;
                    half4 color = SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_LinearRepeat, uv, _BlitMipLevel);
                        
                    // Modify the sampled color
                    return half4(0, _Intensity, 0, 1) * color;
                }
    
                ENDHLSL
            }
        }
    }
    
  4. ColorBlitRendererFeature 添加到通用渲染器资源。

    Add Renderer Feature
    添加渲染器功能

    有关如何添加渲染器功能的信息,请参阅页面 如何将渲染器功能添加到渲染器

    对于此示例,将强度属性设置为 1.5。

  5. Unity 显示以下视图

    Final scene and Game views
    最终场景和游戏视图

    注意:要在 XR 中可视化示例,请将项目配置为使用 XR SDK。 将 MockHMD XR 插件添加到项目。将渲染模式属性设置为单通道实例化

示例已完成。

其他资源

有关在兼容模式下执行 Blit 操作的更多信息,请参阅 URP 14(Unity 2022)文档中的使用纹理部分

URP 中兼容模式下完整可脚本化渲染器功能的示例
URP 的可脚本化渲染通道兼容模式 API 参考