Unity Web Shader IDE
Full source <URP>/Shaders/XR/XRMotionVector.shader ShaderLab / HLSL 104 lines 13 symbols 1 includes Hide source Show source
XRMotionVector.shader <URP>/Shaders/XR/XRMotionVector.shader
Language
ShaderLab / HLSL
Lines
104
Symbols
13
Includes
1
Open IDE root

<URP>/Shaders/XR/XRMotionVector.shader full source

Shader "Hidden/Universal Render Pipeline/XR/XRMotionVector"
{
    SubShader
    {
        Tags{ "RenderPipeline" = "UniversalPipeline" }

        Pass
        {
            Name "XR Camera MotionVectors"

            Cull Off
            ZWrite On
            ColorMask RGBA

            // Stencil test to only fill the pixels that doesn't have object motion data filled by the previous pass.
            Stencil
            {
                WriteMask 1
                ReadMask 1
                Ref 1
                Comp NotEqual

                // Fail Zero
                // Pass Zero
            }

            HLSLPROGRAM
            #pragma target 3.5

            #pragma vertex Vert
            #pragma fragment Frag

            // -------------------------------------
            // Includes
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            // -------------------------------------
            // Constants
            float _SpaceWarpNDCModifier;

            // -------------------------------------
            // Structs
            struct Attributes
            {
                uint vertexID   : SV_VertexID;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varyings
            {
                float4 position : SV_POSITION;
                float4 posCS : TEXCOORD0;
                float4 prevPosCS : TEXCOORD1;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            // -------------------------------------
            // Vertex
            Varyings Vert(Attributes input)
            {
                Varyings output;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);

                output.position = GetFullScreenTriangleVertexPosition(input.vertexID, 1 - UNITY_NEAR_CLIP_VALUE);

                // Reconstruct world position
                // We can use the clip space as is because contrary to the convention mentioned in Common.hlsl (RP Core),
                // this clip space is already Y-up
                float3 posWS = ComputeWorldSpacePosition(output.position, UNITY_MATRIX_I_VP);
                
                // Multiply with current and previous non-jittered view projection
                output.posCS = mul(_NonJitteredViewProjMatrix, float4(posWS, 1.0));
                output.prevPosCS = mul(_PrevViewProjMatrix, float4(posWS, 1.0));

                return output;
            }

            // -------------------------------------
            // Fragment
            half4 Frag(Varyings input) : SV_Target
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

                // Non-uniform raster needs to keep the posNDC values in float to avoid additional conversions
                // since uv remap functions use floats
                float3 posNDC = input.posCS.xyz * rcp(input.posCS.w);
                float3 prevPosNDC = input.prevPosCS.xyz * rcp(input.prevPosCS.w);

                // Calculate forward velocity
                float3 velocity = (posNDC - prevPosNDC);
                
                #if UNITY_UV_STARTS_AT_TOP
                velocity.y = velocity.y * _SpaceWarpNDCModifier;
                #endif

                return float4(velocity.xyz, 0);
            }
            ENDHLSL
        }
    }
    Fallback Off
}