Render Texture Atlas with multiple camera on URP

Hi, I’m trying to create one Atlas where multiple cameras render their view into the one RenderTexture.

I’m currently working on URP14, Unity version 2022.3.2f1.

Camera Stacking is not available because I want to use atlas as shader’s global texture or as a texture for a specific material.

I applied the Render Feature below to the camera that assigned Render Texture as Output Texture to perform Camera Rect clipping.

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class ApplyCameraRect : ScriptableRendererFeature
{
    private ApplyCameraRectPass pass;
    public RenderPassEvent _renderPassEvent = RenderPassEvent.BeforeRenderingShadows;
    public RenderTexture _targetTexture;
    public override void Create()
    {
        pass = new ApplyCameraRectPass(_renderPassEvent, _targetTexture);
    }
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(pass);
    }
}
public class ApplyCameraRectPass : ScriptableRenderPass
{
    public RenderTexture targetTexture;
    public ApplyCameraRectPass(RenderPassEvent _evt, RenderTexture _rt)
    {
        renderPassEvent = _evt;
        targetTexture = _rt;
    }
    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
        Rect rect = renderingData.cameraData.camera.rect;
        rect.x = targetTexture.width * rect.x;
        rect.y = targetTexture.height * rect.y;
        rect.width = targetTexture.width * rect.width;
        rect.height = targetTexture.height * rect.height;
        cmd.EnableScissorRect(rect);
    }
    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
    }
}

But as shown in the following image, there is a problem with the second camera overwriting what was drawn by the previous camera.
Camera.clearFlags does nothing within RenderFeature.

How do I prevent the next camera overwriting what the previous camera drew within one Render Texture? Or do you have any suggestions for implementing Render Texture Atlas within URP?

I’d appreciate your advice.

In legacy pipeline, all I need to do for rendering atlas is set up a Rect values on each camera. Only script I need is GetComponent().depthTextureMode = DepthTextureMode.Depth; this one line.

How should I do same thing like this on URP? I don’t get it why setting the camera rect for render texture in URP is complicated.

Perhaps you tried the wrong place?

I see you’ve left out Execute’s body and it gives you two data structures to work with.
RenderingData specifically is ref, so mutable and it’s also available in Setup.

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@17.0/api/UnityEngine.Rendering.Universal.CameraData.html

It contains a clearFlags property and my guess is, @c0d3_m0nk3y from the other thread was right, but you have to use the RenderingData as it could be overriding any global values (e.g. from using Camera.clearDepth) temporarily for this feature to work without altering the global state.

You mean clearDepth? There’s no exact property ‘clearFlags’ on CameraData. I already tried renderingData.cameraData.camera.clearFlags = CameraClearFlags.Nothing; on Execute() function but it didn’t work.

I also tried to move EnableScissorRect() onto Execute() function but it was meaningless.

Yes I meant clearDepth.
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.2/manual/cameras-advanced.html
This seems like the appropriate docs to read.

Since this whole thing is handled by URP, you probably have to play by its rules.
e.g. Overlay camera seems to be what you need for this type of feature. But it also depends on clearDepth for the color buffer.
Otherwise for base camera, you might need to use BackgroundType.Uninitialized (which doesn’t initialize the color buffer). It says it’s best if you use this for full texture manipulation, so not sure what it’ll do with the scissorrect.

I doubt EnableScissorRect should be in execute. It’s clearly a setup command.

Another idea would be to look into the URP package code and see if you can emulate the workflow of another RendererFeature within.

e.g. the FullScreenPassRendererFeature which seems like a base class for post proc, seems to be copying color data for a pass instead of relying on the camera not clearing it.

PS: Can you explain a bit why you can’t use Camera Stacking and whether Atlas refers to a texture asset?

I don’t get it at all

I’ve tried following the tutorials in the official manual, but I can’t create anything more than the tutorials. What courses should I follow to learn the concept of Renderer Feature?

I think there’s a Udemy course on URP which has a section about Renderer Features but I haven’t watched it.