Render from another camera inside a camera's rendering loop
Render from cameras nested inside the render loop of other cameras.
Attach the provided script to a GameObject with a Camera component to nest multiple cameras, that are rendering with RenderPipeline.SubmitRenderRequest, inside the render loop of other cameras.
Note: If your project uses the Universal Render Pipeline (URP), the recommended best practice is to use UniversalRenderPipeline.SingleCameraRequest instead of StandardRequest, to make sure you only render the camera provided to the RenderRequest
API instead of the full stack of cameras.
Attach the script to nest
Follow these steps:
Create a new C# script.
Add the
using
statements shown below and theRequireComponent
attribute with theCamera
type.using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; [RequireComponent(typeof(Camera))] public class InLoopRenderRequest : MonoBehaviour { }
Add a property with the type
Camera
to theInLoopRenderRequest
class.Add a property with the type
RenderTexture
for each callback the camera uses, as shown below:[RequireComponent(typeof(Camera))] public class InLoopRenderRequest : MonoBehaviour { public Camera renderRequestCamera; public RenderTexture onBeginCameraRendering; public RenderTexture onBeginContextRendering; public RenderTexture onEndCameraRendering; public RenderTexture onEndContextRendering; }
Full code example
The following is an example of the finalized code which you attach to the secondary camera:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
[RequireComponent(typeof(Camera))]
public class InLoopRenderRequest : MonoBehaviour
{
// Add a reference to the secondary camera that will render the textures
// It's recommended to disable the secondary camera.
public Camera renderRequestCamera;
// Add references to the Render Textures that will contain the rendered image from the secondary camera.
public RenderTexture onBeginCameraRendering;
public RenderTexture onBeginContextRendering;
public RenderTexture onEndCameraRendering;
public RenderTexture onEndContextRendering;
void OnEnable()
{
// Subscribe to the RenderPipelineManager callbacks
RenderPipelineManager.beginCameraRendering += OnBeginCameraRender;
RenderPipelineManager.beginContextRendering += OnBeginContextRendering;
RenderPipelineManager.endCameraRendering += OnEndCameraRender;
RenderPipelineManager.endContextRendering += OnEndContextRendering;
}
public void OnDisable()
{
// Unsubscribe to the callbacks from RenderPipelineManager when we disable the component
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRender;
RenderPipelineManager.beginContextRendering -= OnBeginContextRendering;
RenderPipelineManager.endCameraRendering -= OnEndCameraRender;
RenderPipelineManager.endContextRendering -= OnEndContextRendering;
}
void SubmitStandardRenderRequest(RenderTexture rt, Camera cam)
{
RenderPipeline.StandardRequest request = new();
// Check that the Scriptable Render Pipeline (SRP) we're using supports the given render data.
if (RenderPipeline.SupportsRenderRequest(cam, request))
{
// Set the request RenderTexture
request.destination = rt;
// Render the camera output to the RenderTexture synchronously
// When this is complete, the RenderTexture in renderTextures[i] contains the scene rendered from the point of view of the secondary cameras
RenderPipeline.SubmitRenderRequest(cam, request);
}
}
// StandardRequest and UniversalRenderPipeline.SingleCameraRequest also trigger RenderPipelineManager callbacks.
// Check that the callbacks are from the GameObject's Camera component to avoid a recursive rendering of the same camera.
private void OnBeginContextRendering(ScriptableRenderContext ctx, List<Camera> cams)
{
if (cams.Contains(GetComponent<Camera>()))
{
SubmitStandardRenderRequest(onBeginContextRendering, renderRequestCamera);
}
}
private void OnEndContextRendering(ScriptableRenderContext ctx, List<Camera> cams)
{
if (cams.Contains(GetComponent<Camera>()))
{
SubmitStandardRenderRequest(onEndContextRendering, renderRequestCamera);
}
}
private void OnBeginCameraRender(ScriptableRenderContext ctx, Camera cam)
{
if (cam == GetComponent<Camera>())
{
SubmitStandardRenderRequest(onBeginCameraRendering, renderRequestCamera);
}
}
private void OnEndCameraRender(ScriptableRenderContext ctx, Camera cam)
{
if (cam == GetComponent<Camera>())
{
SubmitStandardRenderRequest(onEndCameraRendering, renderRequestCamera);
}
}
}