No Description
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.

MotionVectors.cs 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. using UnityEngine.Experimental.Rendering;
  2. namespace UnityEngine.Rendering.Universal
  3. {
  4. // Motion vector data that persists over frames. (per camera)
  5. internal sealed class MotionVectorsPersistentData
  6. {
  7. #region Fields
  8. private const int k_EyeCount = 2;
  9. readonly Matrix4x4[] m_Projection = new Matrix4x4[k_EyeCount];
  10. readonly Matrix4x4[] m_View = new Matrix4x4[k_EyeCount];
  11. readonly Matrix4x4[] m_ViewProjection = new Matrix4x4[k_EyeCount];
  12. readonly Matrix4x4[] m_PreviousProjection = new Matrix4x4[k_EyeCount];
  13. readonly Matrix4x4[] m_PreviousView = new Matrix4x4[k_EyeCount];
  14. readonly Matrix4x4[] m_PreviousViewProjection = new Matrix4x4[k_EyeCount];
  15. readonly Matrix4x4[] m_PreviousPreviousProjection = new Matrix4x4[k_EyeCount];
  16. readonly Matrix4x4[] m_PreviousPreviousView = new Matrix4x4[k_EyeCount];
  17. readonly int[] m_LastFrameIndex = new int[k_EyeCount];
  18. readonly float[] m_PrevAspectRatio = new float[k_EyeCount];
  19. float m_deltaTime;
  20. float m_lastDeltaTime;
  21. Vector3 m_worldSpaceCameraPos;
  22. Vector3 m_previousWorldSpaceCameraPos;
  23. Vector3 m_previousPreviousWorldSpaceCameraPos;
  24. #endregion
  25. #region Constructors
  26. internal MotionVectorsPersistentData()
  27. {
  28. Reset();
  29. }
  30. #endregion
  31. #region Properties
  32. internal int lastFrameIndex
  33. {
  34. get => m_LastFrameIndex[0];
  35. }
  36. internal Matrix4x4 viewProjection
  37. {
  38. get => m_ViewProjection[0];
  39. }
  40. internal Matrix4x4 previousViewProjection
  41. {
  42. get => m_PreviousViewProjection[0];
  43. }
  44. internal Matrix4x4[] viewProjectionStereo
  45. {
  46. get => m_ViewProjection;
  47. }
  48. internal Matrix4x4[] previousViewProjectionStereo
  49. {
  50. get => m_PreviousViewProjection;
  51. }
  52. internal Matrix4x4[] projectionStereo
  53. {
  54. get => m_Projection;
  55. }
  56. internal Matrix4x4[] previousProjectionStereo
  57. {
  58. get => m_PreviousProjection;
  59. }
  60. internal Matrix4x4[] previousPreviousProjectionStereo
  61. {
  62. get => m_PreviousPreviousProjection;
  63. }
  64. internal Matrix4x4[] viewStereo
  65. {
  66. get => m_View;
  67. }
  68. internal Matrix4x4[] previousViewStereo
  69. {
  70. get => m_PreviousView;
  71. }
  72. internal Matrix4x4[] previousPreviousViewStereo
  73. {
  74. get => m_PreviousPreviousView;
  75. }
  76. internal float deltaTime
  77. {
  78. get => m_deltaTime;
  79. }
  80. internal float lastDeltaTime
  81. {
  82. get => m_lastDeltaTime;
  83. }
  84. internal Vector3 worldSpaceCameraPos
  85. {
  86. get => m_worldSpaceCameraPos;
  87. }
  88. internal Vector3 previousWorldSpaceCameraPos
  89. {
  90. get => m_previousWorldSpaceCameraPos;
  91. }
  92. internal Vector3 previousPreviousWorldSpaceCameraPos
  93. {
  94. get => m_previousPreviousWorldSpaceCameraPos;
  95. }
  96. #endregion
  97. public void Reset()
  98. {
  99. for (int i = 0; i < k_EyeCount; i++)
  100. {
  101. m_Projection[i] = Matrix4x4.identity;
  102. m_View[i] = Matrix4x4.identity;
  103. m_ViewProjection[i] = Matrix4x4.identity;
  104. m_PreviousProjection[i] = Matrix4x4.identity;
  105. m_PreviousView[i] = Matrix4x4.identity;
  106. m_PreviousViewProjection[i] = Matrix4x4.identity;
  107. m_PreviousProjection[i] = Matrix4x4.identity;
  108. m_PreviousView[i] = Matrix4x4.identity;
  109. m_PreviousViewProjection[i] = Matrix4x4.identity;
  110. m_LastFrameIndex[i] = -1;
  111. m_PrevAspectRatio[i] = -1;
  112. }
  113. m_deltaTime = 0.0f;
  114. m_lastDeltaTime = 0.0f;
  115. m_worldSpaceCameraPos = Vector3.zero;
  116. m_previousWorldSpaceCameraPos = Vector3.zero;
  117. m_previousPreviousWorldSpaceCameraPos = Vector3.zero;
  118. }
  119. static private int GetXRMultiPassId(XRPass xr)
  120. {
  121. #if ENABLE_VR && ENABLE_XR_MODULE
  122. return xr.enabled ? xr.multipassId : 0;
  123. #else
  124. return 0;
  125. #endif
  126. }
  127. public void Update(UniversalCameraData cameraData)
  128. {
  129. int eyeIndex = GetXRMultiPassId(cameraData.xr);
  130. // XR multipass renders the frame twice, avoid updating camera history twice.
  131. bool xrMultipassEnabled = cameraData.xr.enabled && !cameraData.xr.singlePassEnabled;
  132. bool isNewFrame = !xrMultipassEnabled || (eyeIndex == 0);
  133. int frameIndex = Time.frameCount;
  134. // Update per-frame data once regardless of how many eyes are being rendered
  135. if (isNewFrame)
  136. {
  137. // For per-frame data, we only care if this is the first frame for eye zero because eye zero
  138. // is always updated once per frame regardless of how XR is configured.
  139. bool isPreviousFrameDataInvalid = (m_LastFrameIndex[0] == -1);
  140. float deltaTime = Time.deltaTime;
  141. Vector3 worldSpaceCameraPos = cameraData.camera.transform.position;
  142. // Use the current delta time if the previous time is invalid
  143. if (isPreviousFrameDataInvalid)
  144. {
  145. m_lastDeltaTime = deltaTime;
  146. m_deltaTime = deltaTime;
  147. m_previousPreviousWorldSpaceCameraPos = worldSpaceCameraPos;
  148. m_previousWorldSpaceCameraPos = worldSpaceCameraPos;
  149. m_worldSpaceCameraPos = worldSpaceCameraPos;
  150. }
  151. m_lastDeltaTime = m_deltaTime;
  152. m_deltaTime = deltaTime;
  153. m_previousPreviousWorldSpaceCameraPos = m_previousWorldSpaceCameraPos;
  154. m_previousWorldSpaceCameraPos = m_worldSpaceCameraPos;
  155. m_worldSpaceCameraPos = worldSpaceCameraPos;
  156. }
  157. // A camera could be rendered multiple times per frame, only update the view projections if needed
  158. bool aspectChanged = m_PrevAspectRatio[eyeIndex] != cameraData.aspectRatio;
  159. if (m_LastFrameIndex[eyeIndex] != frameIndex || aspectChanged)
  160. {
  161. bool isPreviousFrameDataInvalid = (m_LastFrameIndex[eyeIndex] == -1) || aspectChanged;
  162. int numActiveViews = cameraData.xr.enabled ? cameraData.xr.viewCount : 1;
  163. // Make sure we don't try to handle more views than we expect to support
  164. Debug.Assert(numActiveViews <= k_EyeCount);
  165. for (int viewIndex = 0; viewIndex < numActiveViews; ++viewIndex)
  166. {
  167. int targetIndex = viewIndex + eyeIndex;
  168. var gpuP = GL.GetGPUProjectionMatrix(cameraData.GetProjectionMatrixNoJitter(viewIndex), true);
  169. var gpuV = cameraData.GetViewMatrix(viewIndex);
  170. var gpuVP = gpuP * gpuV;
  171. // If the data for the previous frame is invalid, we need to set all previous frame data
  172. // to the current frame data to avoid generating invalid motion vectors
  173. if (isPreviousFrameDataInvalid)
  174. {
  175. m_PreviousPreviousProjection[targetIndex] = gpuP;
  176. m_PreviousProjection[targetIndex] = gpuP;
  177. m_Projection[targetIndex] = gpuP;
  178. m_PreviousPreviousView[targetIndex] = gpuV;
  179. m_PreviousView[targetIndex] = gpuV;
  180. m_View[targetIndex] = gpuV;
  181. m_ViewProjection[targetIndex] = gpuVP;
  182. m_PreviousViewProjection[targetIndex] = gpuVP;
  183. }
  184. // Shift all matrices to the next position
  185. m_PreviousPreviousProjection[targetIndex] = m_PreviousProjection[targetIndex];
  186. m_PreviousProjection[targetIndex] = m_Projection[targetIndex];
  187. m_Projection[targetIndex] = gpuP;
  188. m_PreviousPreviousView[targetIndex] = m_PreviousView[targetIndex];
  189. m_PreviousView[targetIndex] = m_View[targetIndex];
  190. m_View[targetIndex] = gpuV;
  191. m_PreviousViewProjection[targetIndex] = m_ViewProjection[targetIndex];
  192. m_ViewProjection[targetIndex] = gpuVP;
  193. }
  194. m_LastFrameIndex[eyeIndex] = frameIndex;
  195. m_PrevAspectRatio[eyeIndex] = cameraData.aspectRatio;
  196. }
  197. }
  198. // Set global motion vector matrix GPU constants.
  199. public void SetGlobalMotionMatrices(RasterCommandBuffer cmd, XRPass xr)
  200. {
  201. var passID = GetXRMultiPassId(xr);
  202. #if ENABLE_VR && ENABLE_XR_MODULE
  203. if (xr.enabled && xr.singlePassEnabled)
  204. {
  205. cmd.SetGlobalMatrixArray(ShaderPropertyId.previousViewProjectionNoJitterStereo, previousViewProjectionStereo);
  206. cmd.SetGlobalMatrixArray(ShaderPropertyId.viewProjectionNoJitterStereo, viewProjectionStereo);
  207. }
  208. else
  209. #endif
  210. {
  211. cmd.SetGlobalMatrix(ShaderPropertyId.previousViewProjectionNoJitter, previousViewProjectionStereo[passID]);
  212. cmd.SetGlobalMatrix(ShaderPropertyId.viewProjectionNoJitter, viewProjectionStereo[passID]);
  213. }
  214. }
  215. }
  216. }