123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- Shader "Hidden/kMotion/ObjectMotionVectors"
- {
- SubShader
- {
- Pass
- {
- // Lightmode tag required setup motion vector parameters by C++ (legacy Unity)
- Tags{ "LightMode" = "MotionVectors" }
- HLSLPROGRAM
- // Required to compile gles 2.0 with standard srp library
- #pragma prefer_hlslcc gles
- #pragma exclude_renderers d3d11_9x
- #pragma target 3.0
- //--------------------------------------
- // GPU Instancing
- #pragma multi_compile_instancing
- #pragma vertex vert
- #pragma fragment frag
- // -------------------------------------
- // Includes
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
- #if defined(USING_STEREO_MATRICES)
- float4x4 _PrevViewProjMStereo[2];
- #define _PrevViewProjM _PrevViewProjMStereo[unity_StereoEyeIndex]
- #else
- #define _PrevViewProjM _PrevViewProjMatrix
- #endif
- // -------------------------------------
- // Structs
- struct Attributes
- {
- float4 position : POSITION;
- float3 positionOld : TEXCOORD4;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- struct Varyings
- {
- float4 positionCS : SV_POSITION;
- float4 positionVP : TEXCOORD0;
- float4 previousPositionVP : TEXCOORD1;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- UNITY_VERTEX_OUTPUT_STEREO
- };
- // -------------------------------------
- // Vertex
- Varyings vert(Attributes input)
- {
- Varyings output = (Varyings)0;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_TRANSFER_INSTANCE_ID(input, output);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
- output.positionCS = TransformObjectToHClip(input.position.xyz);
- // this works around an issue with dynamic batching
- // potentially remove in 5.4 when we use instancing
- #if defined(UNITY_REVERSED_Z)
- output.positionCS.z -= unity_MotionVectorsParams.z * output.positionCS.w;
- #else
- output.positionCS.z += unity_MotionVectorsParams.z * output.positionCS.w;
- #endif
- output.positionVP = mul(UNITY_MATRIX_VP, mul(UNITY_MATRIX_M, input.position));
- const float4 prevPos = (unity_MotionVectorsParams.x == 1) ? float4(input.positionOld, 1) : input.position;
- output.previousPositionVP = mul(_PrevViewProjM, mul(unity_MatrixPreviousM, prevPos));
- return output;
- }
- // -------------------------------------
- // Fragment
- half4 frag(Varyings input) : SV_Target
- {
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
- // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled
- bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;
- if (forceNoMotion)
- {
- return float4(0.0, 0.0, 0.0, 0.0);
- }
- // Calculate positions
- float4 posVP = input.positionVP;
- float4 prevPosVP = input.previousPositionVP;
- posVP.xy *= rcp(posVP.w);
- prevPosVP.xy *= rcp(prevPosVP.w);
- // Calculate velocity
- float2 velocity = (posVP.xy - prevPosVP.xy);
- #if UNITY_UV_STARTS_AT_TOP
- velocity.y = -velocity.y;
- #endif
- // Convert from Clip space (-1..1) to NDC 0..1 space.
- // Note it doesn't mean we don't have negative value, we store negative or positive offset in NDC space.
- // Note: ((positionCS * 0.5 + 0.5) - (previousPositionCS * 0.5 + 0.5)) = (velocity * 0.5)
- return float4(velocity.xy * 0.5, 0, 0);
- }
- ENDHLSL
- }
- }
- }
|