Version: 2019.4
Scheduling and executing rendering commands in the Scriptable Render Pipeline
Creating a custom render pipeline

Scriptable Render Pipeline (SRP) Batcher

The SRP Batcher is a renderingThe process of drawing graphics to the screen (or to a render texture). By default, the main camera in Unity renders its view to the screen. More info
See in Glossary
loop that speeds up your CPU rendering in ScenesA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary
with many Materials that use the same ShaderA program that runs on the GPU. More info
See in Glossary
Variant.

The Scriptable Render Pipeline (SRP) Batcher speeds up CPU rendering in Scenes with many Materials that use the same Shader Variant.
The Scriptable Render Pipeline (SRP) Batcher speeds up CPU rendering in Scenes with many Materials that use the same Shader Variant.

Using the SRP Batcher

To use the SRP Batcher, your Project must use a Scriptable Render Pipeline. This can either be:

To activate the SRP Batcher in URP:

  1. In the Project windowA window that shows the contents of your Assets folder (Project tab) More info
    See in Glossary
    , select the URP Asset.
  2. In the InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
    See in Glossary
    for the Asset, go to the Advanced section, and enable the SRP Batcher checkbox.
You can de-activate the SRP Batcher in the Asset for URP or HDRP, respectively. The SRP Batcher is enabled by default.
You can de-activate the SRP Batcher in the Asset for URP or HDRP, respectively. The SRP Batcher is enabled by default.

In HDRP, the SRP Batcher is enabled by default and you should not disable it. However, if you want to temporarily disable the SRP Batcher for debugging purposes:

  1. In the Project window, select the HDRP Asset.
  2. In the Inspector for the Asset, enter Debug Mode. This changes how the HDRP Asset displays its properties and makes the SRP Batcher property appear.
  3. Disable the SRP Batcher checkbox.

You can also enable or disable the SRP Batcher at run time. To do this, toggle the following global variable in your C# code:

GraphicsSettings.useScriptableRenderPipelineBatching = true;

Supported platforms

The SRP Batcher works on almost all platforms. This table shows supported platforms and the minimal Unity version required.

Platform Minimum Unity version required
Windows DirectX 11 2018.2
PlayStation 4 2018.2
Vulkan 2018.3
OSX Metal 2018.3
iOSApple’s mobile operating system. More info
See in Glossary
Metal
2018.3
Nintendo Switch 2018.3
Xbox One DirectX 11 2019.2
OpenGL 4.2 and higher 2019.1
OpenGL ES 3.1 and higher 2019.1
Xbox One DirectX 12 2019.1
Windows DirectX 12 2019.1

Note: For XRAn umbrella term encompassing Virtual Reality (VR), Augmented Reality (AR) and Mixed Reality (MR) applications. Devices supporting these forms of interactive applications can be referred to as XR devices. More info
See in Glossary
, you can only use the SRP Batcher with the SinglePassInstanced mode.

How the SRP Batcher works

In Unity, you can modify the properties of any Material at any time during a frame. However, this has some drawbacks. For example, there is a lot of work to do when a DrawCall is using a new Material. So the more Materials you have in a Scene, the more CPU Unity has to use to set up GPU data. The traditional way to deal with this is to reduce the number of DrawCalls to optimize the CPU rendering cost, because Unity has to set up a lot of things before issuing the DrawCall. And the real CPU cost comes from that setup, not from the GPU DrawCall itself, which is just some bytes that Unity needs to push to the GPU command buffer.

The SRP Batcher reduces the GPU setup between DrawCalls by batching a sequence of Bind and Draw GPU commands.

The batching of Bind and Draw commands reduces the GPU setup between draw calls.
The batching of Bind and Draw commands reduces the GPU setup between draw calls.

To get the maximum performance for your rendering, these batches must be as large as possible. To achieve this, you can use as many different Materials with the same Shader as you want, but you must use as few Shader Variants as possible.

During the inner render loop, when Unity detects a new Material, the CPU collects all properties and sets up different constant buffers in GPU memory. The number of GPU buffers depends on how the Shader declares its CBUFFERs.

To speed up the general case where a Scene uses a lot of different Materials, but very few Shader variants, the SRP natively integrates paradigms such as GPU data persistency.

The SRP Batcher is a low-level render loop that makes Material data persist in GPU memory. If the Material content does not change, the SRP Batcher does not need to set up and upload the buffer to the GPU. Instead, the SRP Batcher uses a dedicated code path to quickly update the Unity Engine properties in a large GPU buffer, like this:

This is the SRP Batcher rendering workflow. The SRP Batcher uses a dedicated code path to quickly update the Unity Engine properties in a large GPU buffer.
This is the SRP Batcher rendering workflow. The SRP Batcher uses a dedicated code path to quickly update the Unity Engine properties in a large GPU buffer.

Here, the CPU only handles the Unity Engine properties, labelled Per Object large buffer in the above diagram. All Materials have persistent CBUFFERs located in GPU memory, which are ready to use. This speeds up rendering because: All Material content now persists in GPU memory. Dedicated code manages a large per-object GPU CBUFFER for all per-object properties.

SRP Batcher compatibility

In any given Scene, some objects compatible with the SRP Batcher, and some are not. Even when using non-compatible objects, Unity renders the Scene properly. This is because compatible objects use the SRP Batcher code path, and others use the standard SRP code path.

For the SRP Batcher code path to render an object:

  • The rendered object must be a meshThe main graphics primitive of Unity. Meshes make up a large part of your 3D worlds. Unity supports triangulated or Quadrangulated polygon meshes. Nurbs, Nurms, Subdiv surfaces must be converted to polygons. More info
    See in Glossary
    or skinned mesh. It cannot be a particle.
  • The shader must be compatible with the SRP Batcher. All Lit and Unlit Shaders in HDRP and URP fit this requirement (except for the Particles versions of these shaders).
  • The rendered object must not use MaterialPropertyBlocks.

For a Shader to be compatible with the SRP Batcher:

  • You must declare all built-in engine properties in a single CBUFFER named “UnityPerDraw”. For example, unity_ObjectToWorld, or unity_SHAr.
  • You must declare all Material properties in a single CBUFFER named UnityPerMaterial.

You can see the compatibility status of a Shader in the Inspector panel.

You can check the compatibility of your Shaders in the INspector panel for the specific Shader.
You can check the compatibility of your Shaders in the INspector panel for the specific Shader.

Profiling with the SRP Batcher

To measure the speed increase in your Scene when using the SRP Batcher, add the SRPBatcherProfiler.cs C# script from the SRP Batcher template to your Scene. When this script is running: Toggle the overlay display using the F8 key. You can also turn SRP Batcher on and off during play using the F9 key.

The overlay looks like this:

In the SRP Batcher overlay, you can find detailed information about whats happening in the SRP Batcher.
In the SRP Batcher overlay, you can find detailed information about what’s happening in the SRP Batcher.

The time measurements are in milliseconds (ms), and show how much time the CPU spent in Unity SRP rendering loops.

Note: Time here equals cumulated time of all RenderLoop.Draw and Shadows.Draw markers that are called during a frame, regardless of the thread owner. For example, if you see 1.31ms SRP Batcher code path, maybe the draw calls have spent 0.31ms on the main thread, and 1ms is spread over all graphic jobs.

Overlay information

This table describes each setting in the SRP Batcher overlay that is visible in Play mode:

Name in overlay Description
(SRP batcher ON) / (SRP batcher OFF) Indicates whether the current SRP Batcher is enabled or not. To toggle the SRP Batcher on or off, press F9.
CPU Rendering time Indicates the total, cumulative amount of time that SRP loops have spent in the CPU, regardless of which multi-thread mode is being used, for example single, client/worker or graphics jobs. This is where you can see the effects of the SRP Batcher the most. To see the optimization of the batcher, try toggling it on and off to see the difference in CPU usage. In this example, the total is 2.11 milliseconds.
(incl RT idle): Indicates the idle time that the SRP has spent in the render thread. This could mean that the app was in a client/worker mode with no graphics jobs, which happens when the render thread has to wait for the graphics commands on the main thread. In this example, the render thread was idle for 0.36 milliseconds.
SRP Batcher code path (flushes) Indicates the time your game or app spent in the SRP Batcher code path. This is broken down into the amount of time that your game spent rendering All objects (except for shadow passes) (1.18ms), and ShadowsA UI component that adds a simple outline effect to graphic components such as Text or Image. It must be on the same GameObject as the graphic component. More info
See in Glossary
(1.13ms). If the Shadows number is high, try reducing the number of shadow casting lights in your Scene, or choose a lower number of Cascades in your Render Pipeline Asset. In this example, it was 1.31ms.
The (flush(s)) number indicates how many times Unity flushed the Scene because it encountered a new Shader Variant (in this example: 89). A lower number of flushes is always better, because that means there was a low number of Shader Variants in the frame.
Standard code path (flushes) Indicates the time Unity spent rendering objects that are not compatible with the SRP Batcher, such as particles.
In this example, the SRP Batcher flushed 81 objects in 0.80ms: 0.09ms for shadow passes and 0.71ms for all other passes.
Global Main Loop: (FPS) Indicates the global main loop time in milliseconds, and the equivalent in frames per secondThe frequency at which consecutive frames are displayed in a running game. More info
See in Glossary
(FPS). Note. FPSSee first person shooter, frames per second.
See in Glossary
is not linear, so if you see FPS increase by 20, this doesn’t necessarily mean you’ve optimized the Scene. To see whether the SRP Batcher optimizes your Scene rendering, toggle it ON and OFF, and compare the numbers under CPU Rendering time.

SRP Batcher data in the Unity Frame Debugger

You can check the status on SRP Batcher “batches” in the Frame Debugger window.

To check the status of SRP Batcher batches:

  1. In the Editor, go to Window > Analysis > Frame Debugger > Render Camera > Render Opaques, and expand the RenderLoopNewBatcher.Draw list.
  2. Click on the SRP Batch you want to inspect.

The SRP Batch details show you how many draw calls were used, which keywords were attached to the Shader, and the reason why that specific draw call wasn’t batched with the previous one. In the example below, the stated reason is: Node use different shader keywords. This means that the Shader keywords for that batch are different than the keywords in the previous batch. Because the SRP Batcher used a different Shader Variant, the batch was broken. If an SRP batch has a low number of draw calls, you’re most likely using too many Shader Variants.

In the Frame Debugger window, you can find details about individual batches, including why the SRP Batcher created a new batch instead of continuing the existing one.
In the Frame Debugger window, you can find details about individual batches, including why the SRP Batcher created a new batch instead of continuing the existing one.

If you’re writing your own SRP instead of using URP or HDRP, try to write a generic “uber” Shader with a minimal amount of keywords (but you can use as many Material parameters and Material Properties inside each Material as you want).

Scheduling and executing rendering commands in the Scriptable Render Pipeline
Creating a custom render pipeline