ObjectMotionVectors.shader 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. Shader "Hidden/kMotion/ObjectMotionVectors"
  2. {
  3. SubShader
  4. {
  5. Pass
  6. {
  7. // Lightmode tag required setup motion vector parameters by C++ (legacy Unity)
  8. Tags{ "LightMode" = "MotionVectors" }
  9. HLSLPROGRAM
  10. // Required to compile gles 2.0 with standard srp library
  11. #pragma prefer_hlslcc gles
  12. #pragma exclude_renderers d3d11_9x
  13. #pragma target 3.0
  14. //--------------------------------------
  15. // GPU Instancing
  16. #pragma multi_compile_instancing
  17. #pragma vertex vert
  18. #pragma fragment frag
  19. // -------------------------------------
  20. // Includes
  21. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  22. #if defined(USING_STEREO_MATRICES)
  23. float4x4 _PrevViewProjMStereo[2];
  24. #define _PrevViewProjM _PrevViewProjMStereo[unity_StereoEyeIndex]
  25. #else
  26. #define _PrevViewProjM _PrevViewProjMatrix
  27. #endif
  28. // -------------------------------------
  29. // Structs
  30. struct Attributes
  31. {
  32. float4 position : POSITION;
  33. float3 positionOld : TEXCOORD4;
  34. UNITY_VERTEX_INPUT_INSTANCE_ID
  35. };
  36. struct Varyings
  37. {
  38. float4 positionCS : SV_POSITION;
  39. float4 positionVP : TEXCOORD0;
  40. float4 previousPositionVP : TEXCOORD1;
  41. UNITY_VERTEX_INPUT_INSTANCE_ID
  42. UNITY_VERTEX_OUTPUT_STEREO
  43. };
  44. // -------------------------------------
  45. // Vertex
  46. Varyings vert(Attributes input)
  47. {
  48. Varyings output = (Varyings)0;
  49. UNITY_SETUP_INSTANCE_ID(input);
  50. UNITY_TRANSFER_INSTANCE_ID(input, output);
  51. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  52. output.positionCS = TransformObjectToHClip(input.position.xyz);
  53. // this works around an issue with dynamic batching
  54. // potentially remove in 5.4 when we use instancing
  55. #if defined(UNITY_REVERSED_Z)
  56. output.positionCS.z -= unity_MotionVectorsParams.z * output.positionCS.w;
  57. #else
  58. output.positionCS.z += unity_MotionVectorsParams.z * output.positionCS.w;
  59. #endif
  60. output.positionVP = mul(UNITY_MATRIX_VP, mul(UNITY_MATRIX_M, input.position));
  61. const float4 prevPos = (unity_MotionVectorsParams.x == 1) ? float4(input.positionOld, 1) : input.position;
  62. output.previousPositionVP = mul(_PrevViewProjM, mul(unity_MatrixPreviousM, prevPos));
  63. return output;
  64. }
  65. // -------------------------------------
  66. // Fragment
  67. half4 frag(Varyings input) : SV_Target
  68. {
  69. UNITY_SETUP_INSTANCE_ID(input);
  70. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  71. // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled
  72. bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;
  73. if (forceNoMotion)
  74. {
  75. return float4(0.0, 0.0, 0.0, 0.0);
  76. }
  77. // Calculate positions
  78. float4 posVP = input.positionVP;
  79. float4 prevPosVP = input.previousPositionVP;
  80. posVP.xy *= rcp(posVP.w);
  81. prevPosVP.xy *= rcp(prevPosVP.w);
  82. // Calculate velocity
  83. float2 velocity = (posVP.xy - prevPosVP.xy);
  84. #if UNITY_UV_STARTS_AT_TOP
  85. velocity.y = -velocity.y;
  86. #endif
  87. // Convert from Clip space (-1..1) to NDC 0..1 space.
  88. // Note it doesn't mean we don't have negative value, we store negative or positive offset in NDC space.
  89. // Note: ((positionCS * 0.5 + 0.5) - (previousPositionCS * 0.5 + 0.5)) = (velocity * 0.5)
  90. return float4(velocity.xy * 0.5, 0, 0);
  91. }
  92. ENDHLSL
  93. }
  94. }
  95. }