Version: 2020.1
Render Texture
Movie Textures

Custom Render Textures

Custom Render Textures are a special type of texture that allows you to update a texture with a shader. They are an extension to Render Textures. You can use Custom Render Textures to create complex simulations like caustics, ripple simulation for rain effects and liquid splatters.

Custom Render Textures provides a scripting and Shader framework to help with more complicated configuration like partial or multi-pass updates or varying update frequency. To use this framework you need to assign a Material to the Custom Render Texture asset. To do this:

  1. Create a new Custom Render Texture asset
  2. Assign a Material to it in the inspector window in the Material property

This Material updates the content of the texture according to its parameters. You can assign any kind of Material to a Custom Render Texture, including a Material that is assigned to another Custom Render Texture.

Render Pipeline Compatibility

The table below describes the compatibility between the Custom Render Textures feature and each render pipeline:

Feature Built-in Render Pipeline Universal Render Pipeline (URP) High Definition Render Pipeline (HDRP) Custom Scriptable Render Pipeline (SRP)
Custom Render Textures Yes (1) Yes (1) Yes (1) Yes (1)

Note:

  1. Currently, you can’t create Materials that update and initialize Custom Render Textures in Shader Graph. You can only create Unity shaders that operate on Custom Render Textures by writing ShaderLab code.

Свойства

The Custom Render Textures inspector window displays many of the same properties as the Render Texture inspector, and some properties specific to Custom Render Textures.

Render Texture:

Property: Function:
Dimension Dimension of the Render Texture.
     2D Makes the Render Texture two dimensional.
     Cube Makes the Render Texture a cube map.
     3D Makes the Render Texture three dimensional.
Size The size of the Render Texture in pixels.
Color Format The Format of the Render Texture.
sRGB (Color Render Texture) Enable to allow the Render Texture to use sRGB read/write conversions (Read Only).
Enable Mip Maps Enable to allow the Render Texture to use Mip Maps.
Auto generate Mip Maps Enable to automatically generate Mip Maps.
Wrap Mode Defines how the Texture behaves when tiled.
     Repeat The Texture repeats itself as a tile.
     Clamp The Texture’s edges are stretched.
Filter Mode Defines how Unity filters the Texture when it is stretched by 3D transformations.
     Point The Texture becomes blocky up close.
     Bilinear The Texture becomes blurry up close.
     Trilinear Like Bilinear, but the Texture also blurs between different mip levels.
Aniso Level Increases Texture quality when viewing the texture at a steep angle. Good for floor and ground textures.

Custom Texture:

These properties are exclusive to Custom Render Textures. Custom Texture parameters are separated into three categories:

  • Material: Defines what shader is used to update the texture.

  • Initialization: Controls how the texture is initialized before the shader performs any updates.

  • Update: Controls how the shader updates the texture.

Property: Function:
Material The Material used to update the Custom Render Texture
     Shader Pass The Shader Pass used to update the Custom Render Texture. The combo box shows all passes available in your Material.
Initialization Mode The rate at which Unity initializes the texture.
     OnLoad Unity initializes the texture once upon creation.
     Realtime Unity initializes the texture every frame.
     OnDemand Unity initializes the texture on demand from the script.
Source How Unity texture initializes the texture.
     Texture and Color A texture multiplied by a color initializes the texture.
         Initialization Color Defines the color that initializes the Custom Render Texture. If you also provide an Initialization Texture, the multiplication of the color and the texture initializes the the Custom Render Texture.
         Initialization Texture Defines the texture that initializes the Custom Render Texture. If you also provide an Initialization Color, the multiplication of the color and the texture initializes the the Custom Render Texture.
     Material A Material initialises the texture.
         Initialization Material Defines the Material that initializes the Custom Render Texture.
Update Mode The rate at which the shader updates the Custom Render Texture..
     OnLoad The shader updates the texture once upon creation.
     Realtime The shader updates the texture every frame.
     OnDemand The shader updates the texture on demand from script.
Period The period in seconds at which Unity updates a real-time texture. A value of 0.0 updates every frame. This property is only available in real time.
Double Buffered Double-buffers the texture. Each update swaps the two buffers. This allows you to read the result of the preceding update in the shader.
Wrap Update Zones Enable to allow partial update zones to wrap around the border of the texture.
Cubemap Faces (Cubemap only) Series of toggle allowing user to enable/disable update on each of the cube map faces.
Update Zone Space Coordinate system in which update zones are defined.
     Normalized All coordinates and sizes are between 0 and 1 with the top-left corner starting at (0, 0).
     Pixel All coordinates and sizes are expressed in pixels limited by the width and height of the texture. Top-left corner starting at (0, 0).
Update Zone List List of update zones for the texture (see below for more details).

Exporting Custom Render Texture to a file:

You can export Custom Render Textures to a PNG or EXR file (depending on the texture format) via the contextual “Export” menu.

Update Zones:

When Unity updates the Custom Render Texture, the Material updates the whole texture at once by default. The Custom Texture allows you to define zones of partial update. You can use this to define as many zones as you want and the order in which the zones are processed.

This is useful for various purposes. For example, you could have multiple small zones to splat water drops on the texture and then do a full pass to simulate the ripples. This can also be used as an optimization when you know that you don’t need to update the full texture.

Update zones have their own set of properties. The Update Zone Space is visible in the display. Coordinates depend on the Dimension of the texture: 2D for 2D and Cube textures, or 3D for 3D textures.

Property: Function:
Center Coordinate of the center of the update zone.
Size The size of the update zone.
Rotation The orientation of the update zone in degrees (unavailable for 3D textures).
Shader Pass Defines the Shader Pass to use for this update zone. If you set this property as default, this update zone uses the Shader Pass that you defined in the main part of the inspector. Otherwise it will use the Shader Pass you provide.
Swap (Double Buffer) (Only for Double Buffered textures) If Swap is enabled, Unity swaps the buffers before processing this update zone.

Double Buffered Custom Textures

Custom Render Textures can be double-buffered. This means that inside one Custom Render Texture there are two textures which Unity can swap after each update. This allows you to read the result of the last update while writing a new result in the Custom Render Texture. This is particularly useful if the shader needs to use the content already written in the texture but cannot mix the values with classic blend modes. This is also required if the shaders have to sample different pixels of the preceding result.

Performance warning: Double buffering currently involves a copy of the texture at each swap which can lead to a drop in performance depending on the frequency at which it is done and the resolution of the texture.

Chaining Custom Render Textures

Custom Render Textures require a Material to be updated. This Material can have textures as an input. This means that you can use a Custom Render Texture as an input to generate another one. This way, you can chain up several Custom Textures to generate a more complex multi-step simulation. The system will correctly handle all the dependencies so that the different updates happen in the right order.

Writing a shader for a Custom Render Texture

Updating a Custom Texture is like performing 2D post processing in a Render Texture. To help you write your custom texture shaders, here is a small framework with utility functions and built-in helper variables.

The following shader example fills the texture with a color multiplied by a color:

Shader "CustomRenderTexture/Simple"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _Tex("InputTex", 2D) = "white" {}
     }

     SubShader
     {
        Lighting Off
        Blend One Zero

        Pass
        {
            CGPROGRAM
            #include "UnityCustomRenderTexture.cginc"
            #pragma vertex CustomRenderTextureVertexShader
            #pragma fragment frag
            #pragma target 3.0

            float4      _Color;
            sampler2D   _Tex;

            float4 frag(v2f_customrendertexture IN) : COLOR
            {
                return _Color * tex2D(_Tex, IN.localTexcoord.xy);
            }
            ENDCG
            }
    }
}

The only mandatory steps when writing a shader for a custom texture are:

  • #include "UnityCustomRenderTexture.cginc"

  • Use the provided Vertex Shader CustomRenderTextureVertexShader

  • Use the provided input structure v2f_customrendertexture for the pixel shader

Here is another example of a shader used in an initialization Material:

Shader "CustomRenderTexture/CustomTextureInit"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _Tex("InputTex", 2D) = "white" {}
    }

    SubShader
    {
        Lighting Off
        Blend One Zero

        Pass
        {
            CGPROGRAM
            #include "UnityCustomRenderTexture.cginc"

            #pragma vertex InitCustomRenderTextureVertexShader
            #pragma fragment frag
            #pragma target 3.0

            float4      _Color;
            sampler2D   _Tex;

            float4 frag(v2f_init_customrendertexture IN) : COLOR
            {
                return _Color * tex2D(_Tex, IN.texcoord.xy);
            }
            ENDCG
        }
    }
}

Same as for the update shader, the only mandatory steps are these:

* #include “UnityCustomRenderTexture.cginc”

  • Use the provided Vertex Shader InitCustomRenderTextureVertexShader

  • Use the provided input structure v2f_init_customrendertexture for the pixel shader

This example shader includes a set of built-in values. This includes Global values, values from the v2f_customrendertexture structure and values from the v2f_init_customrendertexture structure.

The input values from the v2f_customrendertexture structure:

Имя Type Значение
localTexcoord float3 Texture coordinates relative to the update zone being currently processed.
globalTexcoord float3 Texture coordinates relative to the Custom Render Texture itself
primitiveID uint Index of the update zone being currently processed.
direction float3 For Cube Custom Render Texture, direction of the current pixel inside the cubemap.

The input values from the v2f_init_customrendertexture structure:

Имя Type Значение
texcoord float3 Texture coordinates relative to the Custom Render Texture itself.

Global values:

Имя Type Значение
_CustomRenderTextureWidth float Width of the Custom Texture in pixels
_CustomRenderTextureHeight float Height of the Custom Texture in pixels
_CustomRenderTextureDepth float Depth of the Custom Texture in pixels (only for 3D textures, otherwise will always be equal to 1).
_CustomRenderTextureCubeFace float Only for Cubemaps: Index of the current cubemap face being processed (-X, +X, -Y, +Y, -Z, +Z).
_CustomRenderTexture3DSlice float Only for 3D textures: Index of the current 3D slice being processed.
_SelfTexture2D Sampler2D For double buffered textures: Texture containing the result of the last update before the last swap.
_SelfTextureCube SamplerCUBE For double buffered textures: Texture containing the result of the last update before the last swap.
_SelfTexture3D Sampler3D For double buffered textures: Texture containing the result of the last update before the last swap.

Controlling Custom Render Texture from Script

Most of the functionalities described here can be accessed via the Scripting API. Changing Material parameters, update frequency, update zones, requesting an update etc, can all be done with the script.

Any update requested for the Custom Texture will happen at a very specific time at the beginning of the frame with the current state of the Custom Texture. This guarantees that any Material using this texture will have the up-to-date result.

This means that this kind of pattern:

customRenderTexture.updateZones = updateZones1;
customRenderTexture.Update();
customRenderTexture.updateZones = updateZones2;
customRenderTexture.Update();

Will not yield the “expected” result of one update done with the first array of update zones and then a second update with the other array. This will perform two updates with the second array.

Essentially, any property modified will only be active in the next frame.


  • 2017–05–18 Page published

  • New feature in Unity 2017.1 NewIn20171

Render Texture
Movie Textures