137 lines
4.8 KiB
Markdown
137 lines
4.8 KiB
Markdown
|
|
# Write a render pipeline with render graph in SRP Core
|
||
|
|
|
||
|
|
Create a custom render pipeline using the [render graph system](render-graph-system.md) in SRP Core.
|
||
|
|
|
||
|
|
**Note:** This page is about creating a custom render pipeline. To use the render graph system in a prebuilt Unity pipeline, refer to either [Render graph system in URP](https://docs.unity3d.com/Manual/urp/render-graph.html) or [Render graph system in HDRP](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/index.html?subfolder=/manual/render-graph-introduction.html).
|
||
|
|
|
||
|
|
1. In your class that inherits `RenderPipeline`, create an instance of a [`RenderGraph`](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html). For example:
|
||
|
|
|
||
|
|
```c#
|
||
|
|
public class MyRenderPipeline : RenderPipeline
|
||
|
|
{
|
||
|
|
...
|
||
|
|
|
||
|
|
RenderGraph myRenderGraph;
|
||
|
|
myRenderGraph = new RenderGraph("MyRenderGraph");
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Note:** To optimize memory usage, use only one instance. You can use more than one instance of a render graph, but Unity doesn't share resources across `RenderGraph` instances.
|
||
|
|
|
||
|
|
For more information about creating a render pipeline class, refer to [Creating a custom render pipeline](srp-custom.md).
|
||
|
|
|
||
|
|
2. In your render loop, create the parameters to initialize the render graph, using the `RenderGraphParameters` API. For example:
|
||
|
|
|
||
|
|
```c#
|
||
|
|
void RenderMyCamera(ScriptableRenderContext context, Camera cameraToRender)
|
||
|
|
{
|
||
|
|
context.SetupCameraProperties(cameraToRender);
|
||
|
|
var cmd = CommandBufferPool.Get("ExampleCommandBuffer");
|
||
|
|
|
||
|
|
RenderGraphParameters rgParams = new RenderGraphParameters
|
||
|
|
{
|
||
|
|
commandBuffer = cmd,
|
||
|
|
scriptableRenderContext = context,
|
||
|
|
currentFrameIndex = Time.frameCount,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
For more information about creating a render loop, refer to [Create a simple render loop in a custom render pipeline](srp-creating-simple-render-loop.md).
|
||
|
|
|
||
|
|
|
||
|
|
3. Initialize the render graph by calling the [`BeginRecording`](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html) method. For example:
|
||
|
|
|
||
|
|
```c#
|
||
|
|
myRenderGraph.BeginRecording(renderGraphParams);
|
||
|
|
```
|
||
|
|
|
||
|
|
4. Run the render passes by calling the [`EndRecordingAndExecute`](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html) method. For example:
|
||
|
|
|
||
|
|
```c#
|
||
|
|
myRenderGraph.BeginRecording(renderGraphParams);
|
||
|
|
|
||
|
|
// Add render passes here.
|
||
|
|
|
||
|
|
myRenderGraph.EndRecordingAndExecute();
|
||
|
|
```
|
||
|
|
|
||
|
|
For more information about adding render passes, refer to [Write a render pass using the render graph system](render-graph-write-render-pass.md)
|
||
|
|
|
||
|
|
5. Execute the rendering commands. For more information, refer to [Execute rendering commands in a custom render pipeline](srp-using-scriptable-render-context.md).
|
||
|
|
|
||
|
|
6. In the render pipeline class, call the `Cleanup()` method on the RenderGraph instance to free the resources the render graph allocated. For example:
|
||
|
|
|
||
|
|
```c#
|
||
|
|
myRenderGraph.Cleanup();
|
||
|
|
myRenderGraph = null;
|
||
|
|
```
|
||
|
|
|
||
|
|
7. After the last camera renders, call the `EndFrame` method to deallocate any resources that the render graph hasn't used since the last frame.
|
||
|
|
|
||
|
|
```c#
|
||
|
|
myRenderGraph.EndFrame();
|
||
|
|
```
|
||
|
|
|
||
|
|
## Example render pipeline template
|
||
|
|
|
||
|
|
This code template is simplified. It demonstrates the clearest workflow, rather than the most efficient runtime performance.
|
||
|
|
|
||
|
|
```c#
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.Rendering;
|
||
|
|
using UnityEngine.Rendering.RenderGraphModule;
|
||
|
|
|
||
|
|
public class ExampleRenderPipeline : RenderPipeline
|
||
|
|
{
|
||
|
|
private RenderGraph myRenderGraph;
|
||
|
|
|
||
|
|
public ExampleRenderPipeline(ExampleRenderPipelineAsset asset)
|
||
|
|
{
|
||
|
|
myRenderGraph = new RenderGraph("My render graph");
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void Render(ScriptableRenderContext context, List<Camera> cameras)
|
||
|
|
{
|
||
|
|
foreach (var cam in cameras)
|
||
|
|
{
|
||
|
|
if (cam.enabled)
|
||
|
|
{
|
||
|
|
RenderCamera(context, cam);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void RenderCamera(ScriptableRenderContext context, Camera cameraToRender)
|
||
|
|
{
|
||
|
|
context.SetupCameraProperties(cameraToRender);
|
||
|
|
var cmd = CommandBufferPool.Get("Example command buffer");
|
||
|
|
|
||
|
|
RenderGraphParameters rgParams = new RenderGraphParameters
|
||
|
|
{
|
||
|
|
commandBuffer = cmd,
|
||
|
|
scriptableRenderContext = context,
|
||
|
|
currentFrameIndex = Time.frameCount,
|
||
|
|
};
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
myRenderGraph.BeginRecording(rgParams);
|
||
|
|
// Add render passes here.
|
||
|
|
myRenderGraph.EndRecordingAndExecute();
|
||
|
|
}
|
||
|
|
catch (Exception e)
|
||
|
|
{
|
||
|
|
if (renderGraph.ResetGraphAndLogException(e))
|
||
|
|
throw;
|
||
|
|
}
|
||
|
|
|
||
|
|
context.ExecuteCommandBuffer(cmd);
|
||
|
|
CommandBufferPool.Release(cmd);
|
||
|
|
context.Submit();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|