Version: Unity 6 (6000.0)
Language : English
Create a texture in the render graph system in URP
Use a texture in a render pass in URP

Import a texture into the render graph system in URP

When you create a texture in the render graph system in a render pass, the render graph system handles the creation and disposal of the texture. This process means the texture might not exist in the next frame, and other camerasA component which creates an image of a particular viewpoint in your scene. The output is either drawn to the screen or captured as a texture. More info
See in Glossary
might not be able to use it.

To make sure a texture is available across frames and cameras, import it into the render graph system using the ImportTexture API.

You can import a texture if you use a texture created outside the render graph system. For example, you can create a render textureA special type of Texture that is created and updated at runtime. To use them, first create a new Render Texture and designate one of your Cameras to render into it. Then you can use the Render Texture in a Material just like a regular Texture. More info
See in Glossary
that points to a texture in your project, such as a texture asset, and use it as the input to a render pass.

The render graph system doesn’t manage the lifetime of imported textures. As a result, the following applies:

  • You must dispose of the imported render texture to free up the memory it uses when you’re finished with it.
  • URP can’t cull render passes that use imported textures. As a result, rendering might be slower.

For more information about the RTHandle API, refer to Using the RTHandle system.

Import a texture

To import a texture, in the RecordRenderGraph method of your ScriptableRenderPass class, follow these steps:

  1. Create a render texture handle using the RTHandle API.

    For example:

    private RTHandle renderTextureHandle;
    
  2. Create a RenderTextureDescriptor object with the texture properties you need.

    For example:

    RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 0);
    
  3. Use the ReAllocateIfNeeded method to create a render texture and attach it to the render texture handle. This method creates a render texture only if the render texture handle is null, or the render texture has different properties to the render texture descriptor.

    For example:

    RenderingUtils.ReAllocateIfNeeded(ref renderTextureHandle, textureProperties, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "My render texture" );
    
  4. Import the texture, to convert the RTHandle object to a TextureHandle object the render graph system can use.

    For example:

    TextureHandle texture = renderGraph.ImportTexture(renderTextureHandle);
    

You can then use the TextureHandle object to read from or write to the render texture.

Import a texture from your project

To import a texture from your project, such as an imported texture attached to a material, follow these steps:

  1. Use the RTHandles.Alloc API to create a render texture handle from the external texture.

    For example:

    RTHandle renderTexture = RTHandles.Alloc(texture);
    
  2. Import the texture, to convert the RTHandle object to a TextureHandle object that the render graph system can use.

    For example:

    TextureHandle textureHandle = renderGraph.ImportTexture(renderTexture);
    

You can then use the TextureHandle object to read from or write to the render texture.

Dispose of the render texture

You must free the memory a render texture uses at the end of a render pass, using the Dispose method.

public void Dispose()
{
    renderTexture.Release();
}

Example

The following Scriptable Renderer Feature contains an example render pass that copies a texture asset to a temporary texture. To use this example, follow these steps:

  1. Add this Scriptable Renderer Feature to a URP Asset. Refer to Inject a pass using a Scriptable Renderer Feature.
  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
    window of the URP Asset, add a texture to the Texture To Use property.
  3. Use the Frame Debugger to check the texture the render pass adds.
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering;

public class BlitFromExternalTexture : ScriptableRendererFeature
{
    // The texture to use as input 
    public Texture2D textureToUse;

    BlitFromTexture customPass;

    public override void Create()
    {
        // Create an instance of the render pass, and pass in the input texture 
        customPass = new BlitFromTexture(textureToUse);

        customPass.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(customPass);
    }

    class BlitFromTexture : ScriptableRenderPass
    {
        class PassData
        {
            internal TextureHandle textureToRead;
        }

        private Texture2D texturePassedIn;

        public BlitFromTexture(Texture2D textureIn)
        {
            // In the render pass's constructor, set the input texture
            texturePassedIn = textureIn;
        }

        public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameContext)
        {
            using (var builder = renderGraph.AddRasterRenderPass<PassData>("Copy texture", out var passData))
            {
                // Create a temporary texture and set it as the render target
                RenderTextureDescriptor textureProperties = new RenderTextureDescriptor(Screen.width, Screen.height, RenderTextureFormat.Default, 0);
                TextureHandle texture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, textureProperties, "My texture", false);
                builder.SetRenderAttachment(texture, 0, AccessFlags.Write);

                // Create a render texture from the input texture
                RTHandle rtHandle = RTHandles.Alloc(texturePassedIn);

                // Create a texture handle that the shader graph system can use
                TextureHandle textureToRead = renderGraph.ImportTexture(rtHandle);

                // Add the texture to the pass data
                passData.textureToRead = textureToRead;

                // Set the texture as readable
                builder.UseTexture(passData.textureToRead, AccessFlags.Read);

                builder.AllowPassCulling(false);

                builder.SetRenderFunc((PassData data, RasterGraphContext context) => ExecutePass(data, context));
            }
        }

        static void ExecutePass(PassData data, RasterGraphContext context)
        {          
            // Copy the imported texture to the render target
            Blitter.BlitTexture(context.cmd, data.textureToRead, new Vector4(0.8f,0.6f,0,0), 0, false);
        }
    }
}

Additional resources

Create a texture in the render graph system in URP
Use a texture in a render pass in URP