MotionVectorRenderPass.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using System;
  2. using UnityEngine.Experimental.Rendering;
  3. namespace UnityEngine.Rendering.Universal.Internal
  4. {
  5. sealed class MotionVectorRenderPass : ScriptableRenderPass
  6. {
  7. #region Fields
  8. const string kPreviousViewProjectionMatrix = "_PrevViewProjMatrix";
  9. #if ENABLE_VR && ENABLE_XR_MODULE
  10. const string kPreviousViewProjectionMatrixStero = "_PrevViewProjMStereo";
  11. #endif
  12. const string kMotionVectorTexture = "_MotionVectorTexture";
  13. const GraphicsFormat m_TargetFormat = GraphicsFormat.R16G16_SFloat;
  14. static readonly string[] s_ShaderTags = new string[] { "MotionVectors" };
  15. RenderTargetHandle m_MotionVectorHandle; //Move to UniversalRenderer like other passes?
  16. readonly Material m_CameraMaterial;
  17. readonly Material m_ObjectMaterial;
  18. PreviousFrameData m_MotionData;
  19. ProfilingSampler m_ProfilingSampler = ProfilingSampler.Get(URPProfileId.MotionVectors);
  20. #endregion
  21. #region Constructors
  22. internal MotionVectorRenderPass(Material cameraMaterial, Material objectMaterial)
  23. {
  24. renderPassEvent = RenderPassEvent.AfterRenderingSkybox;
  25. m_CameraMaterial = cameraMaterial;
  26. m_ObjectMaterial = objectMaterial;
  27. }
  28. #endregion
  29. #region State
  30. internal void Setup(PreviousFrameData frameData)
  31. {
  32. m_MotionData = frameData;
  33. }
  34. public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
  35. {
  36. var rtd = cameraTextureDescriptor;
  37. rtd.graphicsFormat = m_TargetFormat;
  38. // Configure Render Target
  39. m_MotionVectorHandle.Init(kMotionVectorTexture);
  40. cmd.GetTemporaryRT(m_MotionVectorHandle.id, rtd, FilterMode.Point);
  41. ConfigureTarget(m_MotionVectorHandle.Identifier(), m_MotionVectorHandle.Identifier());
  42. }
  43. #endregion
  44. #region Execution
  45. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  46. {
  47. if (m_CameraMaterial == null || m_ObjectMaterial == null)
  48. return;
  49. // Get data
  50. var camera = renderingData.cameraData.camera;
  51. // Never draw in Preview
  52. if (camera.cameraType == CameraType.Preview)
  53. return;
  54. // Profiling command
  55. CommandBuffer cmd = CommandBufferPool.Get();
  56. using (new ProfilingScope(cmd, m_ProfilingSampler))
  57. {
  58. ExecuteCommand(context, cmd);
  59. var cameraData = renderingData.cameraData;
  60. #if ENABLE_VR && ENABLE_XR_MODULE
  61. if (cameraData.xr.enabled && cameraData.xr.singlePassEnabled)
  62. {
  63. m_CameraMaterial.SetMatrixArray(kPreviousViewProjectionMatrixStero, m_MotionData.previousViewProjectionMatrixStereo);
  64. m_ObjectMaterial.SetMatrixArray(kPreviousViewProjectionMatrixStero, m_MotionData.previousViewProjectionMatrixStereo);
  65. }
  66. else
  67. #endif
  68. {
  69. Shader.SetGlobalMatrix(kPreviousViewProjectionMatrix, m_MotionData.previousViewProjectionMatrix);
  70. }
  71. // These flags are still required in SRP or the engine won't compute previous model matrices...
  72. // If the flag hasn't been set yet on this camera, motion vectors will skip a frame.
  73. camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
  74. // TODO: add option to only draw either one?
  75. DrawCameraMotionVectors(context, cmd, camera);
  76. DrawObjectMotionVectors(context, ref renderingData, camera);
  77. }
  78. ExecuteCommand(context, cmd);
  79. CommandBufferPool.Release(cmd);
  80. }
  81. DrawingSettings GetDrawingSettings(ref RenderingData renderingData)
  82. {
  83. var camera = renderingData.cameraData.camera;
  84. var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque };
  85. var drawingSettings = new DrawingSettings(ShaderTagId.none, sortingSettings)
  86. {
  87. perObjectData = PerObjectData.MotionVectors,
  88. enableDynamicBatching = renderingData.supportsDynamicBatching,
  89. enableInstancing = true,
  90. };
  91. for (int i = 0; i < s_ShaderTags.Length; ++i)
  92. {
  93. drawingSettings.SetShaderPassName(i, new ShaderTagId(s_ShaderTags[i]));
  94. }
  95. // Material that will be used if shader tags cannot be found
  96. drawingSettings.fallbackMaterial = m_ObjectMaterial;
  97. return drawingSettings;
  98. }
  99. void DrawCameraMotionVectors(ScriptableRenderContext context, CommandBuffer cmd, Camera camera)
  100. {
  101. // Draw fullscreen quad
  102. cmd.DrawProcedural(Matrix4x4.identity, m_CameraMaterial, 0, MeshTopology.Triangles, 3, 1);
  103. ExecuteCommand(context, cmd);
  104. }
  105. void DrawObjectMotionVectors(ScriptableRenderContext context, ref RenderingData renderingData, Camera camera)
  106. {
  107. var drawingSettings = GetDrawingSettings(ref renderingData);
  108. var filteringSettings = new FilteringSettings(RenderQueueRange.opaque, camera.cullingMask);
  109. var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
  110. // Draw Renderers
  111. context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filteringSettings, ref renderStateBlock);
  112. }
  113. #endregion
  114. #region Cleanup
  115. public override void FrameCleanup(CommandBuffer cmd)
  116. {
  117. if (cmd == null)
  118. throw new ArgumentNullException("cmd");
  119. // Reset Render Target
  120. if (m_MotionVectorHandle != RenderTargetHandle.CameraTarget)
  121. {
  122. cmd.ReleaseTemporaryRT(m_MotionVectorHandle.id);
  123. m_MotionVectorHandle = RenderTargetHandle.CameraTarget;
  124. }
  125. }
  126. #endregion
  127. #region CommandBufer
  128. void ExecuteCommand(ScriptableRenderContext context, CommandBuffer cmd)
  129. {
  130. context.ExecuteCommandBuffer(cmd);
  131. cmd.Clear();
  132. }
  133. #endregion
  134. }
  135. }