Version: Unity 6.4 (6000.4)
Language : English
Introduction to variable rate shading
Profile and debug when using variable rate shading

Implement variable rate shading

Follow this workflow to implement image-based variable rate shading (VRS), which uses a texture to define shading rates across screen regions.

  1. Verify hardware compatibility
  2. Create a Scriptable Renderer Feature
  3. Configure color mask textures
  4. Create a shading rate image (SRI)
  5. Apply the SRI texture to the render pass

1. Verify hardware compatibility

Before you begin implementation, ensure the target device supports variable rate shading. Refer to Supported platforms for platform compatibility requirements. To query the support, use the following code example:

if(!Vrs.IsColorMaskTextureConversionSupported()) { 
            Debug.Log("VRS is not supported");  
            return;  
}

For more information, refer to the documentation on Vrs.IsColorMaskTextureConversionSupported(). The ShadingRateInfo class allows you to check additional capabilities supported by the target device for VRSVirtual Reality More info
See in Glossary
.

2. Create a Scriptable Renderer Feature

To implement variable rate shading in your project, you must create a Scriptable Renderer Feature to incorporate a custom render pass into your rendering pipeline. Use the RenderGraph API to write a custom render pass. Unity provides VRS helper functions for scriptable render pipelineA series of operations that take the contents of a Scene, and displays them on a screen. Unity lets you choose from pre-built render pipelines, or write your own. More info
See in Glossary
(SRP) to simplify VRS implementation in your custom render pass.

3. Configure color mask textures

A color mask texture is a regular texture that uses color coding to represent which shading rate to use where on the screen.

1. Set up the color mapping system

A VRS look-up table (LUT) maps colors to specific shading rates. Before creating the LUT in code, configure your color mappings in Project SettingsA broad collection of settings which allow you to configure how Physics, Audio, Networking, Graphics, Input and many other areas of your project behave. More info
See in Glossary
. Follow these steps:

  1. Go to Edit > Project Settings > Graphics > URP > VRS-Runtime Resources.

  2. Configure the following lookup tables:

    • Conversion Lookup Table: Defines which colors map to which shading rates when converting from color mask to SRI values with ColorMaskTextureToShadingRateImage.
    • Visualization Lookup Table: Converts SRI values to colors for visualizing debug values with ShadingRateImageToColorMaskTexture.

The default color mapping is:

  • Red: 1x1 (High quality)
  • Green: 2x2 (Medium quality)
  • Dark Blue: 4x4 (Low quality)

After configuring the color values, create a LUT that uses those values:

VrsLut vrsLut = VrsLut.CreateDefault();

Use the following code to get colors for the shading rates, so you can use the colors to fill the texture.

Color vrsColor1x1 = vrsLut[ShadingRateFragmentSize.FragmentSize1x1]; 
Color vrsColor2x2 = vrsLut[ShadingRateFragmentSize.FragmentSize2x2];  
Color vrsColor4x4 = vrsLut[ShadingRateFragmentSize.FragmentSize4x4];

Use a render pass to create a color mask texture on the CPU using the corresponding VRS colors from the LUT. Alternatively, you can load an existing texture from the disk, for example, if you’re authoring the color texture by hand.

Important: The following steps for texture dimension calculations and color mask generation are required only if you’re creating a color mask texture through a render pass workflow.

2. Calculate device-specific texture dimensions

VRS texture size is determined by the number of tiles that fit across the screen and can differ per platform. You must query the native tile size based on your render target’s dimensions.

var sizeInTiles = ShadingRateImage.GetAllocTileSize(renderTargetWidth, renderTargetHeight);

3. Generate VRS color mask

Configure the texture descriptor with the required properties as follows:

RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(sizeInTiles.x, sizeInTiles.y, RenderTextureFormat.Default, 0);
        
TextureHandle colorMask = UniversalRenderer.CreateRenderGraphTexture(renderGraph, textureProperties, "_ShadingRateColor", false);

4. Create a shading rate image (SRI)

Convert the color mask texture into a shading rate image (SRI) that contains shading rate instructions for the GPU. Unity provides the ShadingRateImage class to create and manage these textures across different platforms.

Convert the rendered color mask to create a native shading rate image (SRI) as follows:

// Create texture descriptor for the shading rate image
RenderTextureDescriptor sriProperties = new RenderTextureDescriptor(sizeInTiles.x, sizeInTiles.y, ShadingRateInfo.graphicsFormat, GraphicsFormat.None);
sriProperties.enableRandomWrite = true;
sriProperties.enableShadingRate = true;

// Create shading rate image texture
TextureHandle sriTextureHandle = UniversalRenderer.CreateRenderGraphTexture(renderGraph, sriProperties, "_ShadingRateImage", false);

// Convert the color mask texture to native SRI format
Vrs.ColorMaskTextureToShadingRateImage(renderGraph, sriTextureHandle, colorMask, TextureDimension.Tex2D, true);

Use the Frame Debugger to view the shading rate image in the Unity Editor.

To visualize the SRI in your application for debugging purposes, use the following code. This code converts the SRI to a standard color texture that you can render like any other texture in any custom render pass.

Vrs.ShadingRateImageToColorMaskTexture(renderGraph, sriTextureHandle, sriDebugColorTextureHandle);

5. Apply the SRI texture to the render pass

After creating the SRI, apply it to the custom render pass you created to enable variable rate shading.

// Bind the SRI texture to the render pass and apply its per-tile shading rates.
if (sriTextureHandle.IsValid())
{ 
    builder.SetShadingRateImageAttachment(sriTextureHandle); 
    builder.SetShadingRateCombiner(ShadingRateCombinerStage.Fragment, ShadingRateCombiner.Override);  
}

This binds the VRS texture to the next draw which enables VRS.

Note: You can set a fixed shading rate for the entire draw using the SetShadingRateFragmentSize API.

Additional resources

Introduction to variable rate shading
Profile and debug when using variable rate shading