# 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 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(); } } ```