撇瞥 发表于 前天 09:55

【URP】Unity 插入自定义RenderPass

自定义渲染通道是一种改变通用渲染管道(URP)如何渲染场景或场景中的对象的方法。自定义呈现通道(RenderPass)包含自己的Render代码,可以在注入点将其添加到RenderPass中。
【从UnityURP开始探索游戏渲染】专栏-直达
添加自定义呈现通道(RenderPass):


[*]使用Scriptable render pass API创建自定义render pass的代码。
[*]将自定的render pass注入到URP管线中的指定注入点中,有两种方式:

[*]用RenderPipelineManager API注入自定义渲染通道
[*]或者通过创建一个可脚本化的RendererFeature添加到URP渲染器中。

使用Scriptable render pass API创建自定义render pass


[*]Example custom render pass
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

internal class ColorBlitPass : ScriptableRenderPass
{
    ProfilingSampler m_ProfilingSampler = new ProfilingSampler("ColorBlit");
    Material m_Material;
    RTHandle m_CameraColorTarget;
    float m_Intensity;

    public ColorBlitPass(Material material)
    {
      m_Material = material;
      renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
    }

    public void SetTarget(RTHandle colorHandle, float intensity)
    {
      m_CameraColorTarget = colorHandle;
      m_Intensity = intensity;
    }

    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
      ConfigureTarget(m_CameraColorTarget);
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
      var cameraData = renderingData.cameraData;
      if (cameraData.camera.cameraType != CameraType.Game)
            return;

      if (m_Material == null)
            return;

      CommandBuffer cmd = CommandBufferPool.Get();
      using (new ProfilingScope(cmd, m_ProfilingSampler))
      {
            m_Material.SetFloat("_Intensity", m_Intensity);
            Blitter.BlitCameraTexture(cmd, m_CameraColorTarget, m_CameraColorTarget, m_Material, 0);
      }
      context.ExecuteCommandBuffer(cmd);
      cmd.Clear();

      CommandBufferPool.Release(cmd);
    }
}
将自定的render pass注入到URP管线中的指定注入点中

用RenderPipelineManager API注入自定义渲染通道


[*]通过RenderPipelineManager的注入点委托提供执行时机,加上Camera的EnqueuePass方法注入自定义RenderPass。
public class EnqueuePass : MonoBehaviour
{
    private BlurSettings settings;   
    private BlurRenderPass blurRenderPass;

    private void OnEnable()
    {
      ...
      blurRenderPass = new BlurRenderPass(settings);
      // Subscribe the OnBeginCamera method to the beginCameraRendering event.
      RenderPipelineManager.beginCameraRendering += OnBeginCamera;
    }

    private void OnDisable()
    {
      RenderPipelineManager.beginCameraRendering -= OnBeginCamera;
      blurRenderPass.Dispose();
      ...
    }

    private void OnBeginCamera(ScriptableRenderContext context, Camera cam)
    {
      ...
      // Use the EnqueuePass method to inject a custom render pass
      cam.GetUniversalAdditionalCameraData()
            .scriptableRenderer.EnqueuePass(blurRenderPass);
    }
}
创建一个可脚本化的RendererFeature

此示例执行将屏幕染成绿色的全屏blit。


[*]要创建自定义渲染通道,创建一个名为ColorBlitPass.cs的新c#脚本,然后从示例自定义渲染通道部分粘贴代码。

[*]注意:这个例子使用了Blitter API。不要使用CommandBuffer。URP中的Blit API。更多信息请参考Blit。
[*]使用上面定义好的定制Render Pass

[*]要创建Scriptable RendererFeature,将自定义渲染通道添加到渲染循环中,请创建一个名为ColorBlitRendererFeature.cs的新c#脚本,然后将示例Scriptable RendererFeature部分中的代码粘贴进来。

[*]Example Scriptable Renderer Feature Scriptable Renderer Feature 添加 render pass 到渲染循环.
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

internal class ColorBlitRendererFeature : ScriptableRendererFeature
{
    public Shader m_Shader;
    public float m_Intensity;

    Material m_Material;

    ColorBlitPass m_RenderPass = null;

    public override void AddRenderPasses(ScriptableRenderer renderer,
                                    ref RenderingData renderingData)
    {
      if (renderingData.cameraData.cameraType == CameraType.Game)
            renderer.EnqueuePass(m_RenderPass);
    }

    public override void SetupRenderPasses(ScriptableRenderer renderer,
                                        in RenderingData renderingData)
    {
      if (renderingData.cameraData.cameraType == CameraType.Game)
      {
            // Calling ConfigureInput with the ScriptableRenderPassInput.Color argument
            // ensures that the opaque texture is available to the Render Pass.
            m_RenderPass.ConfigureInput(ScriptableRenderPassInput.Color);
            m_RenderPass.SetTarget(renderer.cameraColorTargetHandle, m_Intensity);
      }
    }

    public override void Create()
    {
      m_Material = CoreUtils.CreateEngineMaterial(m_Shader);
      m_RenderPass = new ColorBlitPass(m_Material);
    }

    protected override void Dispose(bool disposing)
    {
      CoreUtils.Destroy(m_Material);
    }
}

[*]要创建将像素染成绿色的着色器代码,请创建一个着色器文件,然后从示例着色器部分粘贴代码。
[*]Example shader

[*]着色器执行渲染的GPU端。它从相机中采样颜色纹理,然后输出绿色值设置为所选强度的颜色。
注意:与Blitter API一起使用的着色器必须是手工编码的着色器。图形着色器与Blitter API不兼容。
Shader "ColorBlit"
{
    SubShader
    {
      Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
      LOD 100
      ZWrite Off Cull Off
      Pass
      {
            Name "ColorBlitPass"

            HLSLPROGRAM
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            
            // The Blit.hlsl file provides the vertex shader (Vert),
            // the input structure (Attributes) and the output structure (Varyings)
            #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"

            #pragma vertex Vert
            #pragma fragment frag

            // Set the color texture from the camera as the input texture
            TEXTURE2D_X(_CameraOpaqueTexture);
            SAMPLER(sampler_CameraOpaqueTexture);

            // Set up an intensity parameter
            float _Intensity;

            half4 frag (Varyings input) : SV_Target
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                // Sample the color from the input texture
                float4 color = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, input.texcoord);

                // Output the color from the texture, with the green value set to the chosen intensity
                return color * float4(0, _Intensity, 0, 1);
            }
            ENDHLSL
      }
    }
}

[*]将ColorBlitRendererFeature添加到当前URP Renderer资源中。有关更多信息,请参阅向URP渲染器添加渲染器功能。
[*]要更改亮度,请调整Color Blit Renderer Feature组件中的Intensity属性。
注意:如果项目使用XR,为了使示例可视化,在项目中安装MockHMD XR插件包,然后将渲染模式属性设置为单通道实例化。
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/renderer-features/custom-rendering-pass-workflow-in-urp.html
【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 【URP】Unity 插入自定义RenderPass