arenos-nexus/Arenos Nexus/Library/PackageCache/com.unity.render-pipelines.core@f2c863af5658/Documentation~/in-loop-render-requests.md

140 lines
5.6 KiB
Markdown
Raw Normal View History

2025-09-25 22:01:28 +02:00
# 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](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Rendering.RenderPipeline.SubmitRenderRequest.html), inside the render loop of other cameras.
**Note**: If your project uses the [Universal Render Pipeline](https://docs.unity3d.com/Manual/urp/urp-introduction.html) (URP), the recommended best practice is to use [UniversalRenderPipeline.SingleCameraRequest](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@17.2/api/UnityEngine.Rendering.Universal.UniversalRenderPipeline.SingleCameraRequest.html) instead of [StandardRequest](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Rendering.RenderPipeline.StandardRequest.html), 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:
1. Create a new C# script.
2. Add the `using` statements shown below and the `RequireComponent` attribute with the `Camera` type.
```c#
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
[RequireComponent(typeof(Camera))]
public class InLoopRenderRequest : MonoBehaviour
{
}
```
3. Add a property with the type `Camera` to the `InLoopRenderRequest` class.
4. Add a property with the type `RenderTexture` for each callback the camera uses, as shown below:
```c#
[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:
```c#
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);
}
}
}
```
## Additional resources
- [Render Requests](User-Render-Requests.md)
- [Creating a custom render pipeline](srp-custom.md)