unity-game-engineshaderurp

How to use URP Sample Buffer in custom function node in Unity Shader Graph


I need to sample the source buffer NormalWorld from the URP Sample Buffer for a range of UVs. In order to make this easier, I want to iterate through the range of UVs in a Custom Function Node. My issue is that I do not know how to sample the NormalWorld in a Custom Function Node.

For comparison here is how to do it with the Scene Depth, using the documentation code : https://docs.unity3d.com/Packages/com.unity.shadergraph@5.6/manual/Scene-Depth-Node.html

void Unity_SceneDepth_Raw_float(float4 UV, out float Out) {
    Out = SHADERGRAPH_SAMPLE_SCENE_DEPTH(UV);
}

In a Custom Function Node :

void myCustomDepth_float(float2 uv, out float depth) {
    depth = SHADERGRAPH_SAMPLE_SCENE_DEPTH(uv);
}

Scene Depth & Custom Function Node give same result

And now what is the equivalent code to replicate the same for URP Sample Buffer? :

In a Custom Function Node :

void myCustomNormalWorld_float4(float2 uv, out float4 normalWorld) {
    normalWorld = ...?
}

Implementation Missing


Solution

  • I downloaded the source code of the Graphics git repo of Unity and searched up the implementation of the URP Sample Buffer.

    This led me to a file named UniversalSampleBufferNode.cs where we can find the following implementation :

    case BufferType.NormalWorldSpace:
        s.AppendLine("return SHADERGRAPH_SAMPLE_SCENE_NORMAL(uv);");
        break;
    case BufferType.MotionVectors:
        s.AppendLine("uint2 pixelCoords = uint2(uv * _ScreenSize.xy);");
        s.AppendLine($"return LOAD_TEXTURE2D_X_LOD(_MotionVectorTexture, pixelCoords, 0).xy;");
        break;
    case BufferType.BlitSource:
        s.AppendLine("uint2 pixelCoords = uint2(uv * _ScreenSize.xy);");
        s.AppendLine($"return LOAD_TEXTURE2D_X_LOD(_BlitTexture, pixelCoords, 0);");
        break;
    default:
        s.AppendLine("return 0.0;");
        break;
    

    Each case represents one of the choices of the dropdown for the URP Sample Buffer.

    Solution for NormalWorld:

    void myCustomNormalWorld_float4(float2 uv, out float4 normalWorld) {
        normalWorld = SHADERGRAPH_SAMPLE_SCENE_NORMAL(uv);
    }