How to add blit to render pass after draw renderer list

Hi,

I’m trying to create a outline on objects withing a certain layer mask, to achieve this I’ve begun creating a renderer feature. In it I’m able to render the objects within a certain layer mask, but I’m kinda stuck on trying to blit the new texture and depth to the active color texture and depth respectively.

I have tried creating another pass with the builder but I get the “Rogue context error did you call EndRenderPass()” However using the RenderGraphUtil works fine, and executing the DrawPass twice works fine as well.

Any suggestions on how to achieve this?

This is the code I have so far:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;


public class OutlinRendererFeature : ScriptableRendererFeature
{
    public class OutlineRenderPass : ScriptableRenderPass
    {
        const string _pass_name = "OutlinePass";

        Material _material;
        LayerMask _layer_mask;

        TextureHandle _temp;
        TextureHandle _temp_depth;


        private List<ShaderTagId> _shader_tag_id_list = new List<ShaderTagId>();

        public OutlineRenderPass(LayerMask layer_mask, Material material)
        {
            _layer_mask = layer_mask;
            _material = material;

            requiresIntermediateTexture = true;
        }

        private class PassData
        {
            public RendererListHandle renderer_list_handle;

            public TextureHandle temp;
            public TextureHandle temp_depth;
        }

        private void InitRendererLists(ContextContainer frame_data, ref PassData pass_data, RenderGraph render_graph)
        {
            // Access the relevant frame data from the Universal Render Pipeline
            UniversalRenderingData universal_rendering_data = frame_data.Get<UniversalRenderingData>();
            UniversalCameraData camera_data = frame_data.Get<UniversalCameraData>();
            UniversalLightData light_data = frame_data.Get<UniversalLightData>();

            var sort_flags = camera_data.defaultOpaqueSortFlags;
            RenderQueueRange render_queue_range = RenderQueueRange.opaque;
            FilteringSettings filter_settings = new FilteringSettings(render_queue_range, _layer_mask);

            ShaderTagId[] forward_only_shader_tag_ids = new ShaderTagId[]
            {
                new ShaderTagId("UniversalForwardOnly"),
                new ShaderTagId("UniversalForward"),

                // backward compatability
                new ShaderTagId("SRPDefaultUnlit"),
                new ShaderTagId("LightweightForward")
            };

            _shader_tag_id_list.Clear();

            foreach (ShaderTagId sid in forward_only_shader_tag_ids)
                _shader_tag_id_list.Add(sid);

            DrawingSettings draw_settings = RenderingUtils.CreateDrawingSettings(_shader_tag_id_list, universal_rendering_data, camera_data, light_data, sort_flags);

            var param = new RendererListParams(universal_rendering_data.cullResults, draw_settings, filter_settings);
            pass_data.renderer_list_handle = render_graph.CreateRendererList(param);
        }

        static void ExecuteDrawPass(PassData data, RasterGraphContext context)
        {
            context.cmd.DrawRendererList(data.renderer_list_handle);

        }

        static void ExecuteBlitPass(PassData data, RasterGraphContext context)
        {
            Blitter.BlitColorAndDepth(context.cmd, data.temp, data.temp_depth, new Vector4(1, 1, 0, 0), 0, false);
        }

        public override void RecordRenderGraph(RenderGraph render_graph, ContextContainer frame_data)
        {
            string _pass_name = "Outline Render Pass - Render";
            string _pass_name_2 = "Outline Render Pass - Blit";

            UniversalResourceData resource_data = frame_data.Get<UniversalResourceData>();

            using (var builder = render_graph.AddRasterRenderPass<PassData>(_pass_name, out var pass_data))
            {

                InitRendererLists(frame_data, ref pass_data, render_graph);

                // Make sure the renderer list is valid
                if (!pass_data.renderer_list_handle.IsValid())
                {
                    Debug.LogWarning("Renderer list handle is invalid.");
                    return;
                }

                // color texture
                TextureDesc temp_desc = render_graph.GetTextureDesc(resource_data.activeColorTexture);
                temp_desc.name = $"CameraColor-{OutlineRenderPass._pass_name}";
                temp_desc.clearBuffer = true;
                temp_desc.clearColor = UnityEngine.Color.clear;

                _temp = render_graph.CreateTexture(temp_desc);

                // depth texture
                TextureDesc temp_depth_desc = temp_desc;
                temp_depth_desc.colorFormat = GraphicsFormat.None;
                temp_depth_desc.depthBufferBits = DepthBits.Depth32;

                _temp_depth = render_graph.CreateTexture(temp_depth_desc);


                builder.UseRendererList(pass_data.renderer_list_handle);

                builder.SetRenderAttachment(_temp, 0);

                builder.SetRenderAttachmentDepth(_temp_depth, AccessFlags.Write);

                builder.AllowPassCulling(false);

                builder.SetRenderFunc((PassData data, RasterGraphContext context) => ExecuteDrawPass(data, context));
            }

            //RenderGraphUtils.BlitMaterialParameters para = new(_temp, resource_data.activeColorTexture, _material, 0);
            //render_graph.AddBlitPass(para, passName: "Outline Render Pass");
        }
    }

    OutlineRenderPass _render_pass;

    public LayerMask layerMask;
    public Material material;
    public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingOpaques;

    public override void Create()
    {
        _render_pass = new OutlineRenderPass(layerMask, material);
        _render_pass.renderPassEvent = renderPassEvent;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData rendering_data)
    {
        renderer.EnqueuePass(_render_pass);
    }
}

Does anyone have a possible solution?