# Write a Scriptable Render Pass in Compatibility Mode in URP

> An example of creating a Scriptable Render Pass in Compatibility Mode.

> **Note:**
>
> Unity no longer develops or improves the rendering path that doesn't use the [render graph API](/engine/6000.0/manual/render-pipelines/universal-render-pipeline/customizing-urp/render-graph.md). Use the render graph API instead when developing new graphics features. To use the instructions on this page, enable **Compatibility Mode (Render Graph Disabled)** in URP graphics settings (Editor > **Graphics**).

To create a Scriptable Render Pass in the Universal Render Pipeline (URP), follow these steps:

1. Create a C# script that inherits the `ScriptableRenderPass` class. For example:

   ```lang-cs
   using UnityEngine.Rendering;
   using UnityEngine.Rendering.Universal;

   public class ExampleRenderPass : ScriptableRenderPass
   {
   }
   ```

2. In the class, add variables for the materials and textures you use in the render pass.

   For example, the following code sets up a handle to a texture, and a descriptor to configure the texture.

   ```lang-cs
   private RTHandle textureHandle;
   private RenderTextureDescriptor textureDescriptor;
   ```

3. Override the `Configure` method to set up the render pass. Unity calls this method before executing the render pass.

   For example:

   ```lang-cs
   public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
   {
       //Set the texture size to be the same as the camera target size.
       textureDescriptor.width = cameraTextureDescriptor.width;
       textureDescriptor.height = cameraTextureDescriptor.height;

       //Check if the descriptor has changed, and reallocate the texture handle if necessary.
       RenderingUtils.ReAllocateIfNeeded(ref textureHandle, textureDescriptor);
   }
   ```

4. Override the `Execute` method with your rendering commands. Unity calls this method every frame, once for each camera.

   For example:

   ```lang-cs
   public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
   {
       // Get a CommandBuffer from pool
       CommandBuffer cmd = CommandBufferPool.Get();

       // Add rendering commands to the CommandBuffer
       ...

       // Execute the command buffer and release it back to the pool
       context.ExecuteCommandBuffer(cmd);
       CommandBufferPool.Release(cmd);
   }
   ```

## Inject a render pass into the render loop

To inject a render pass into the render loop in Compatibility Mode, refer to the following:

* [Use the `RenderPipelineManager` API](/engine/6000.0/manual/render-pipelines/universal-render-pipeline/customizing-urp/inject-a-render-pass/inject-render-pass-via-script.md)
* [Use a Scriptable Renderer Feature](/engine/6000.0/manual/render-pipelines/universal-render-pipeline/customizing-urp/inject-a-render-pass/inject-a-pass-using-a-scriptable-renderer-feature.md)

For a complete example, refer to [Example of a Scriptable Renderer Feature in Compatibility mode](/engine/6000.0/manual/render-pipelines/universal-render-pipeline/customizing-urp/compatibility-mode/how-to-fullscreen-blit.md).

## Additional resources

* [Custom render pass workflow](/engine/6000.0/manual/render-pipelines/universal-render-pipeline/customizing-urp/custom-rendering-pass-workflow-in-urp.md)
* [Writing custom shaders in URP](/engine/6000.0/manual/materials-and-shaders/shaders/writing-custom-shaders-urp.md)
