找回密码
 立即注册
首页 业界区 科技 【URP】Unity 插入自定义RenderPass

【URP】Unity 插入自定义RenderPass

奸轲嫣 6 小时前
自定义渲染通道是一种改变通用渲染管道(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
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4. internal class ColorBlitPass : ScriptableRenderPass
    5. {
    6.     ProfilingSampler m_ProfilingSampler = new ProfilingSampler("ColorBlit");
    7.     Material m_Material;
    8.     RTHandle m_CameraColorTarget;
    9.     float m_Intensity;
    10.     public ColorBlitPass(Material material)
    11.     {
    12.         m_Material = material;
    13.         renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
    14.     }
    15.     public void SetTarget(RTHandle colorHandle, float intensity)
    16.     {
    17.         m_CameraColorTarget = colorHandle;
    18.         m_Intensity = intensity;
    19.     }
    20.     public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    21.     {
    22.         ConfigureTarget(m_CameraColorTarget);
    23.     }
    24.     public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    25.     {
    26.         var cameraData = renderingData.cameraData;
    27.         if (cameraData.camera.cameraType != CameraType.Game)
    28.             return;
    29.         if (m_Material == null)
    30.             return;
    31.         CommandBuffer cmd = CommandBufferPool.Get();
    32.         using (new ProfilingScope(cmd, m_ProfilingSampler))
    33.         {
    34.             m_Material.SetFloat("_Intensity", m_Intensity);
    35.             Blitter.BlitCameraTexture(cmd, m_CameraColorTarget, m_CameraColorTarget, m_Material, 0);
    36.         }
    37.         context.ExecuteCommandBuffer(cmd);
    38.         cmd.Clear();
    39.         CommandBufferPool.Release(cmd);
    40.     }
    41. }
    复制代码
将自定的render pass注入到URP管线中的指定注入点中

RenderPipelineManager API注入自定义渲染通道


  • 通过RenderPipelineManager的注入点委托提供执行时机,加上Camera的EnqueuePass方法注入自定义RenderPass。
    1. public class EnqueuePass : MonoBehaviour
    2. {
    3.     [SerializeField] private BlurSettings settings;   
    4.     private BlurRenderPass blurRenderPass;
    5.     private void OnEnable()
    6.     {
    7.         ...
    8.         blurRenderPass = new BlurRenderPass(settings);
    9.         // Subscribe the OnBeginCamera method to the beginCameraRendering event.
    10.         RenderPipelineManager.beginCameraRendering += OnBeginCamera;
    11.     }
    12.     private void OnDisable()
    13.     {
    14.         RenderPipelineManager.beginCameraRendering -= OnBeginCamera;
    15.         blurRenderPass.Dispose();
    16.         ...
    17.     }
    18.     private void OnBeginCamera(ScriptableRenderContext context, Camera cam)
    19.     {
    20.         ...
    21.         // Use the EnqueuePass method to inject a custom render pass
    22.         cam.GetUniversalAdditionalCameraData()
    23.             .scriptableRenderer.EnqueuePass(blurRenderPass);
    24.     }
    25. }
    复制代码
创建一个可脚本化的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 到渲染循环.
      1. using UnityEngine;
      2. using UnityEngine.Rendering;
      3. using UnityEngine.Rendering.Universal;
      4. internal class ColorBlitRendererFeature : ScriptableRendererFeature
      5. {
      6.     public Shader m_Shader;
      7.     public float m_Intensity;
      8.     Material m_Material;
      9.     ColorBlitPass m_RenderPass = null;
      10.     public override void AddRenderPasses(ScriptableRenderer renderer,
      11.                                     ref RenderingData renderingData)
      12.     {
      13.         if (renderingData.cameraData.cameraType == CameraType.Game)
      14.             renderer.EnqueuePass(m_RenderPass);
      15.     }
      16.     public override void SetupRenderPasses(ScriptableRenderer renderer,
      17.                                         in RenderingData renderingData)
      18.     {
      19.         if (renderingData.cameraData.cameraType == CameraType.Game)
      20.         {
      21.             // Calling ConfigureInput with the ScriptableRenderPassInput.Color argument
      22.             // ensures that the opaque texture is available to the Render Pass.
      23.             m_RenderPass.ConfigureInput(ScriptableRenderPassInput.Color);
      24.             m_RenderPass.SetTarget(renderer.cameraColorTargetHandle, m_Intensity);
      25.         }
      26.     }
      27.     public override void Create()
      28.     {
      29.         m_Material = CoreUtils.CreateEngineMaterial(m_Shader);
      30.         m_RenderPass = new ColorBlitPass(m_Material);
      31.     }
      32.     protected override void Dispose(bool disposing)
      33.     {
      34.         CoreUtils.Destroy(m_Material);
      35.     }
      36. }
      复制代码

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

    • 着色器执行渲染的GPU端。它从相机中采样颜色纹理,然后输出绿色值设置为所选强度的颜色。
      注意:与Blitter API一起使用的着色器必须是手工编码的着色器。图形着色器与Blitter API不兼容。
      1. Shader "ColorBlit"
      2. {
      3.     SubShader
      4.     {
      5.         Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
      6.         LOD 100
      7.         ZWrite Off Cull Off
      8.         Pass
      9.         {
      10.             Name "ColorBlitPass"
      11.             HLSLPROGRAM
      12.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
      13.             
      14.             // The Blit.hlsl file provides the vertex shader (Vert),
      15.             // the input structure (Attributes) and the output structure (Varyings)
      16.             #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
      17.             #pragma vertex Vert
      18.             #pragma fragment frag
      19.             // Set the color texture from the camera as the input texture
      20.             TEXTURE2D_X(_CameraOpaqueTexture);
      21.             SAMPLER(sampler_CameraOpaqueTexture);
      22.             // Set up an intensity parameter
      23.             float _Intensity;
      24.             half4 frag (Varyings input) : SV_Target
      25.             {
      26.                 UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
      27.                 // Sample the color from the input texture
      28.                 float4 color = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, input.texcoord);
      29.                 // Output the color from the texture, with the green value set to the chosen intensity
      30.                 return color * float4(0, _Intensity, 0, 1);
      31.             }
      32.             ENDHLSL
      33.         }
      34.     }
      35. }
      复制代码

  • 将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开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册