暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MotionVectorPass.hlsl 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #ifndef SG_MOTION_VECTORS_PASS_INCLUDED
  2. #define SG_MOTION_VECTORS_PASS_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MotionVectorsCommon.hlsl"
  4. struct MotionVectorPassAttributes
  5. {
  6. float3 previousPositionOS : TEXCOORD4; // Contains previous frame local vertex position (for skinned meshes)
  7. #if defined (_ADD_PRECOMPUTED_VELOCITY)
  8. float3 alembicMotionVectorOS : TEXCOORD5; // Alembic precomputed object space motion vector (offset from last frame's position)
  9. #endif
  10. };
  11. // Note: these will have z == 0.0f in the pixel shader to save on bandwidth
  12. struct MotionVectorPassVaryings
  13. {
  14. float4 positionCSNoJitter;
  15. float4 previousPositionCSNoJitter;
  16. };
  17. struct PackedMotionVectorPassVaryings
  18. {
  19. float3 positionCSNoJitter : CLIP_POSITION_NO_JITTER;
  20. float3 previousPositionCSNoJitter : PREVIOUS_CLIP_POSITION_NO_JITTER;
  21. };
  22. PackedMotionVectorPassVaryings PackMotionVectorVaryings(MotionVectorPassVaryings regularVaryings)
  23. {
  24. PackedMotionVectorPassVaryings packedVaryings;
  25. packedVaryings.positionCSNoJitter = regularVaryings.positionCSNoJitter.xyw;
  26. packedVaryings.previousPositionCSNoJitter = regularVaryings.previousPositionCSNoJitter.xyw;
  27. return packedVaryings;
  28. }
  29. MotionVectorPassVaryings UnpackMotionVectorVaryings(PackedMotionVectorPassVaryings packedVaryings)
  30. {
  31. MotionVectorPassVaryings regularVaryings;
  32. regularVaryings.positionCSNoJitter = float4(packedVaryings.positionCSNoJitter.xy, 0, packedVaryings.positionCSNoJitter.z);
  33. regularVaryings.previousPositionCSNoJitter = float4(packedVaryings.previousPositionCSNoJitter.xy, 0, packedVaryings.previousPositionCSNoJitter.z);
  34. return regularVaryings;
  35. }
  36. float3 GetLastFrameDeformedPosition(Attributes input, MotionVectorPassOutput currentFrameMvData, float3 previousPositionOS)
  37. {
  38. Attributes lastFrameInputAttributes = input;
  39. lastFrameInputAttributes.positionOS = previousPositionOS;
  40. VertexDescriptionInputs lastFrameVertexDescriptionInputs = BuildVertexDescriptionInputs(lastFrameInputAttributes);
  41. #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)
  42. lastFrameVertexDescriptionInputs.TimeParameters = _LastTimeParameters.xyz;
  43. #endif
  44. VertexDescription lastFrameVertexDescription = VertexDescriptionFunction(lastFrameVertexDescriptionInputs
  45. #if defined(HAVE_VFX_MODIFICATION)
  46. , currentFrameMvData.vfxGraphProperties
  47. #endif
  48. );
  49. #if defined(HAVE_VFX_MODIFICATION)
  50. lastFrameInputAttributes.positionOS = lastFrameVertexDescription.Position.xyz;
  51. lastFrameInputAttributes = VFXTransformMeshToPreviousElement(lastFrameInputAttributes, currentFrameMvData.vfxElementAttributes);
  52. previousPositionOS = lastFrameInputAttributes.positionOS;
  53. #else
  54. previousPositionOS = lastFrameVertexDescription.Position.xyz;
  55. #endif
  56. return previousPositionOS;
  57. }
  58. // -------------------------------------
  59. // Vertex
  60. void vert(
  61. Attributes input,
  62. MotionVectorPassAttributes passInput,
  63. out PackedMotionVectorPassVaryings packedMvOutput,
  64. out PackedVaryings packedOutput)
  65. {
  66. Varyings output = (Varyings)0;
  67. MotionVectorPassVaryings mvOutput = (MotionVectorPassVaryings)0;
  68. MotionVectorPassOutput currentFrameMvData = (MotionVectorPassOutput)0;
  69. output = BuildVaryings(input, currentFrameMvData);
  70. ApplyMotionVectorZBias(output.positionCS);
  71. packedOutput = PackVaryings(output);
  72. #if defined(HAVE_VFX_MODIFICATION) && !VFX_FEATURE_MOTION_VECTORS
  73. //Motion vector is enabled in SG but not active in VFX
  74. const bool forceNoMotion = true;
  75. #else
  76. const bool forceNoMotion = unity_MotionVectorsParams.y == 0.0;
  77. #endif
  78. if (!forceNoMotion)
  79. {
  80. #if defined(HAVE_VFX_MODIFICATION)
  81. float3 previousPositionOS = currentFrameMvData.vfxParticlePositionOS;
  82. #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)
  83. const bool applyDeformation = false;
  84. #else
  85. const bool applyDeformation = true;
  86. #endif
  87. #else
  88. const bool hasDeformation = unity_MotionVectorsParams.x == 1; // Mesh has skinned deformation
  89. float3 previousPositionOS = hasDeformation ? passInput.previousPositionOS : input.positionOS;
  90. #if defined(AUTOMATIC_TIME_BASED_MOTION_VECTORS) && defined(GRAPH_VERTEX_USES_TIME_PARAMETERS_INPUT)
  91. const bool applyDeformation = true;
  92. #else
  93. const bool applyDeformation = hasDeformation;
  94. #endif
  95. #endif
  96. #if defined(FEATURES_GRAPH_VERTEX)
  97. if (applyDeformation)
  98. previousPositionOS = GetLastFrameDeformedPosition(input, currentFrameMvData, previousPositionOS);
  99. else
  100. previousPositionOS = currentFrameMvData.positionOS;
  101. #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT)
  102. previousPositionOS -= currentFrameMvData.motionVector;
  103. #endif
  104. #endif
  105. #if defined(UNITY_DOTS_INSTANCING_ENABLED) && defined(DOTS_DEFORMED)
  106. // Deformed vertices in DOTS are not cumulative with built-in Unity skinning/blend shapes
  107. // Needs to be called after vertex modification has been applied otherwise it will be
  108. // overwritten by Compute Deform node
  109. ApplyPreviousFrameDeformedVertexPosition(input.vertexID, previousPositionOS);
  110. #endif
  111. #if defined (_ADD_PRECOMPUTED_VELOCITY)
  112. previousPositionOS -= passInput.alembicMotionVectorOS;
  113. #endif
  114. mvOutput.positionCSNoJitter = mul(_NonJitteredViewProjMatrix, float4(currentFrameMvData.positionWS, 1.0f));
  115. #if defined(HAVE_VFX_MODIFICATION)
  116. #if defined(VFX_FEATURE_MOTION_VECTORS_VERTS)
  117. #if defined(FEATURES_GRAPH_VERTEX_MOTION_VECTOR_OUTPUT) || defined(_ADD_PRECOMPUTED_VELOCITY)
  118. #error Unexpected fast path rendering VFX motion vector while there are vertex modification afterwards.
  119. #endif
  120. mvOutput.previousPositionCSNoJitter = VFXGetPreviousClipPosition(input, currentFrameMvData.vfxElementAttributes, mvOutput.positionCSNoJitter);
  121. #else
  122. #if VFX_WORLD_SPACE
  123. //previousPositionOS is already in world space
  124. const float3 previousPositionWS = previousPositionOS;
  125. #else
  126. const float3 previousPositionWS = mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)).xyz;
  127. #endif
  128. mvOutput.previousPositionCSNoJitter = mul(_PrevViewProjMatrix, float4(previousPositionWS, 1.0f));
  129. #endif
  130. #else
  131. mvOutput.previousPositionCSNoJitter = mul(_PrevViewProjMatrix, mul(UNITY_PREV_MATRIX_M, float4(previousPositionOS, 1.0f)));
  132. #endif
  133. }
  134. packedMvOutput = PackMotionVectorVaryings(mvOutput);
  135. }
  136. // -------------------------------------
  137. // Fragment
  138. float4 frag(
  139. // Note: packedMvInput needs to be before packedInput as otherwise we get the following error in the speed tree 8 SG:
  140. // "Non system-generated input signature parameter () cannot appear after a system generated value"
  141. PackedMotionVectorPassVaryings packedMvInput,
  142. PackedVaryings packedInput) : SV_Target
  143. {
  144. Varyings input = UnpackVaryings(packedInput);
  145. MotionVectorPassVaryings mvInput = UnpackMotionVectorVaryings(packedMvInput);
  146. UNITY_SETUP_INSTANCE_ID(input);
  147. SurfaceDescription surfaceDescription = BuildSurfaceDescription(input);
  148. #if defined(_ALPHATEST_ON)
  149. clip(surfaceDescription.Alpha - surfaceDescription.AlphaClipThreshold);
  150. #endif
  151. #if defined(LOD_FADE_CROSSFADE) && USE_UNITY_CROSSFADE
  152. LODFadeCrossFade(input.positionCS);
  153. #endif
  154. return float4(CalcNdcMotionVectorFromCsPositions(mvInput.positionCSNoJitter, mvInput.previousPositionCSNoJitter), 0, 0);
  155. }
  156. #endif