In Unity's Universal Render Pipeline (URP), when adding a custom Scriptable Render Feature and setting the drawing timing (RenderPassEvent) to AfterRenderingOpaque (after drawing an opaque object), etc., a problem may occur where the object you want to draw is not displayed on the screen at all. This is a problem that is difficult to identify because no error is output.

In this article, we will explain how to solve the problem of "losing track of the render target buffer", which is the cause of this rendering not being performed, and ensure that custom rendering is executed.

For beginners: How would you describe this problem in real life?

Let's compare this problem to a real restaurant.

In the restaurant kitchen (URP renderer), the chef is making food (drawing data). Normally, the finished dish is delivered to the designated table (the camera's color target buffer).

However, the situation where the binding process is missing in Render Feature is the same as ``The food is finished, but the slip that tells which table it should be delivered to is missing''. The food is left in the corner of the serving table and never reaches the customer (screen). This is the true reason behind the phenomenon of "No error occurs but nothing appears on the screen." The food must be accompanied by clear instructions (ConfigureTarget), such as "Please take it to this table (buffer)."

Problem symptoms and specific phenomena

When this bug occurs, the following symptoms are observed.

  • Objects that should be drawn through a custom path become completely transparent (not drawn) in the scene view or game view.
  • When checking the drawing command (Draw Call) in Frame Debugger, the process itself is being executed, but the drawing destination is Null or an unintended buffer, and it is not reflected in the final screen.
  • If you change RenderPassEvent, it may be drawn suddenly, but the drawing order will be messed up and it will not look the way you intended.

Possible cause: Why do I lose track of the drawing destination?

URP dynamically switches render targets to optimize drawing performance. Especially at event boundaries, such as immediately after drawing an opaque object, the URP itself temporarily detaches the renderbuffer to bridge the post process.

During this switch, if the custom ScriptableRenderPass does not know where the currently active camera's render target is, it will execute drawing instructions to an invalid buffer or empty area. Because of this, even though it is being drawn, it is not reflected on the final screen and disappears.

Specific solutions and approaches

To solve this problem, do the following two implementations.

1. RenderPassEvent synchronization adjustment

Set the render pass execution timing appropriately. If you want to process an opaque object immediately after it is drawn, specify an event in the constructor.

public class CustomRenderPass : ScriptableRenderPass
{
    public CustomRenderPass()
    {
        this.renderPassEvent = RenderPassEvent.AfterRenderingOpaque;
    }
}

2. Explicitly rebinding a target with ConfigureTarget

In the OnCameraSetup method just before the render pass runs, explicitly retrieve the camera's color and depth targets and reset them as the destination.

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Universal;

public class CustomRenderPass : ScriptableRenderPass
{
    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
        var renderer = renderingData.cameraData.renderer;
        // Call ConfigureTarget with an explicit target
        ConfigureTarget(renderer.cameraColorTargetHandle, renderer.cameraDepthTargetHandle);
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        CommandBuffer cmd = CommandBufferPool.Get("CustomRenderPass");
        using (new ProfilingScope(cmd, new ProfilingSampler("Draw Custom Objects")))
        {
            // Do the drawing process here
        }
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }
}

Confirmation checklist useful in practice

This is a practical checklist that you should check if drawing does not work properly when you introduce a custom render feature.

Confirmation items Confirmation method/measures
Register to URP Asset Is Custom Render Feature added to the list of the URP Renderer data you are using?
Layer mismatch Is the layer of the drawing object not excluded by the drawing settings filter?
Frame Debugger Open Frame Debugger and check if your own drawing pass is running.

Summary

Drawing processing using URP's Custom Render Feature often causes problems where the drawing disappears silently due to timing discrepancies or binding failures. By always explicitly specifying the drawing destination with ConfigureTarget, you can prevent drawing data from getting lost in the pipeline and build stable custom effects.