A custom render pass is a way to change how the Universal Render Pipeline (URP) renders a scene or the objects within a 2D scene. A custom render pass contains your own rendering code, which you insert into the rendering pipeline at an injection point.
To add a custom render pass in a 2D project, refer to the documentation for 3D projects in Custom render pass workflow in URP.
In a 2D project, make the following changes:
ScriptableRenderPass2D class instead of the ScriptableRenderPass class.ScriptableRendererFeature2D class instead of the ScriptableRendererFeature class.renderPassEvent2D property to set a RenderPassEvent2D, instead of the renderPassEvent property. For a list of 2D injection points, refer to Injection points reference for 2D in URP.To access the texture resources used by the URP 2D renderer, including the active 2D light and shadow textures, use the Universal2DResourceData API. For more information, refer to Frame data in the render graph system in URP.
The following 2D Scriptable Renderer Feature contains an example render pass that creates a texture and clears it to yellow. For more information about adding the render pass to the render pipeline, refer to Add a Renderer Feature to a URP Renderer.
Use the Frame Debugger to check the texture the render pass adds.
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering;
// Create a 2D Scriptable Renderer Feature
public class CreateYellowTextureFeature2D : ScriptableRendererFeature2D
{
CreateYellowTexture customPass;
public override void Create()
{
customPass = new CreateYellowTexture();
// Inject the render pass at a 2D injection point
injectionPoint2D = RenderPassEvent2D.AfterRenderingPostProcessing;
customPass.renderPassEvent2D = injectionPoint2D;
customPass.renderPassSortingLayerID = sortingLayerID;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(customPass);
}
// Create a 2D render pass
class CreateYellowTexture : ScriptableRenderPass2D
{
class PassData
{
public TextureHandle cameraColorTexture;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameContext)
{
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Create yellow texture", out var passData))
{
// Get the frame data
UniversalResourceData frameData = frameContext.Get<UniversalResourceData>();
// Create texture properties that match the screen size
TextureDesc textureDesc = frameData.activeColorTexture.GetDescriptor(renderGraph);
textureDesc.msaaSamples = MSAASamples.None;
// Create a temporary texture
passData.cameraColorTexture = renderGraph.CreateTexture(textureDesc);
// Set the texture as the render target
builder.SetRenderAttachment(passData.cameraColorTexture, 0, AccessFlags.Write);
// Make sure the render graph system keeps the render pass, even if it's not used in the final frame.
// Don't use this in production code, because it prevents the render graph system from removing the render pass if it's not needed.
builder.AllowPassCulling(false);
builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => ExecutePass(data, context));
}
}
static void ExecutePass(PassData data, RasterGraphContext context)
{
// Clear the render target to yellow
context.cmd.ClearRenderTarget(true, true, Color.yellow);
}
}
}