Ingen beskrivning
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.

MotionVectorRenderPass.cs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. using System;
  2. using Unity.Collections;
  3. using UnityEngine.Experimental.Rendering;
  4. using UnityEngine.Rendering.RenderGraphModule;
  5. namespace UnityEngine.Rendering.Universal
  6. {
  7. sealed class MotionVectorRenderPass : ScriptableRenderPass
  8. {
  9. #region Fields
  10. internal const string k_MotionVectorTextureName = "_MotionVectorTexture";
  11. internal const string k_MotionVectorDepthTextureName = "_MotionVectorDepthTexture";
  12. internal const GraphicsFormat k_TargetFormat = GraphicsFormat.R16G16_SFloat;
  13. public const string k_MotionVectorsLightModeTag = "MotionVectors";
  14. static readonly string[] s_ShaderTags = new string[] { k_MotionVectorsLightModeTag };
  15. static readonly int s_CameraDepthTextureID = Shader.PropertyToID("_CameraDepthTexture");
  16. static readonly ProfilingSampler s_SetMotionMatrixProfilingSampler = new ProfilingSampler("Set Motion Vector Global Matrices");
  17. RTHandle m_Color;
  18. RTHandle m_Depth;
  19. readonly Material m_CameraMaterial;
  20. readonly FilteringSettings m_FilteringSettings;
  21. private PassData m_PassData;
  22. #endregion
  23. #region Constructors
  24. internal MotionVectorRenderPass(RenderPassEvent evt, Material cameraMaterial, LayerMask opaqueLayerMask)
  25. {
  26. renderPassEvent = evt;
  27. m_CameraMaterial = cameraMaterial;
  28. m_FilteringSettings = new FilteringSettings(RenderQueueRange.opaque,opaqueLayerMask);
  29. m_PassData = new PassData();
  30. base.profilingSampler = ProfilingSampler.Get(URPProfileId.DrawMotionVectors);
  31. ConfigureInput(ScriptableRenderPassInput.Depth);
  32. }
  33. #endregion
  34. #region State
  35. internal void Setup(RTHandle color, RTHandle depth)
  36. {
  37. m_Color = color;
  38. m_Depth = depth;
  39. }
  40. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  41. public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
  42. {
  43. cmd.SetGlobalTexture(m_Color.name, m_Color.nameID);
  44. cmd.SetGlobalTexture(m_Depth.name, m_Depth.nameID);
  45. // Disable obsolete warning for internal usage
  46. #pragma warning disable CS0618
  47. ConfigureTarget(m_Color, m_Depth);
  48. ConfigureClear(ClearFlag.Color | ClearFlag.Depth, Color.black);
  49. // Can become a Store based on 'StoreActionsOptimization.Auto' and/or if a user RendererFeature is added.
  50. // We need to keep the MotionVecDepth in case of a user wants to extend the motion vectors
  51. // using a custom RendererFeature.
  52. ConfigureDepthStoreAction(RenderBufferStoreAction.DontCare);
  53. #pragma warning restore CS0618
  54. }
  55. #endregion
  56. #region Execution
  57. private static void ExecutePass(RasterCommandBuffer cmd, PassData passData, RendererList rendererList)
  58. {
  59. var cameraMaterial = passData.cameraMaterial;
  60. if (cameraMaterial == null)
  61. return;
  62. // Get data
  63. Camera camera = passData.camera;
  64. // Never draw in Preview
  65. if (camera.cameraType == CameraType.Preview)
  66. return;
  67. // These flags are still required in SRP or the engine won't compute previous model matrices...
  68. // If the flag hasn't been set yet on this camera, motion vectors will skip a frame.
  69. camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
  70. // TODO: add option to only draw either one?
  71. DrawCameraMotionVectors(cmd, passData.xr, cameraMaterial);
  72. DrawObjectMotionVectors(cmd, passData.xr, ref rendererList);
  73. }
  74. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  75. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  76. {
  77. ContextContainer frameData = renderingData.frameData;
  78. UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
  79. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  80. var cmd = CommandBufferHelpers.GetRasterCommandBuffer(renderingData.commandBuffer);
  81. // Profiling command
  82. using (new ProfilingScope(cmd,profilingSampler))
  83. {
  84. InitPassData(ref m_PassData, cameraData);
  85. InitRendererLists(ref m_PassData, ref universalRenderingData.cullResults, universalRenderingData.supportsDynamicBatching,
  86. context, default(RenderGraph), false);
  87. ExecutePass(cmd, m_PassData, m_PassData.rendererList);
  88. }
  89. }
  90. private static DrawingSettings GetDrawingSettings(Camera camera, bool supportsDynamicBatching)
  91. {
  92. var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque };
  93. var drawingSettings = new DrawingSettings(ShaderTagId.none, sortingSettings)
  94. {
  95. perObjectData = PerObjectData.MotionVectors,
  96. enableDynamicBatching = supportsDynamicBatching,
  97. enableInstancing = true,
  98. };
  99. for (int i = 0; i < s_ShaderTags.Length; ++i)
  100. {
  101. drawingSettings.SetShaderPassName(i, new ShaderTagId(s_ShaderTags[i]));
  102. }
  103. return drawingSettings;
  104. }
  105. // NOTE: depends on camera depth to reconstruct static geometry positions
  106. private static void DrawCameraMotionVectors(RasterCommandBuffer cmd, XRPass xr, Material cameraMaterial)
  107. {
  108. #if ENABLE_VR && ENABLE_XR_MODULE
  109. bool foveatedRendering = xr.supportsFoveatedRendering;
  110. bool nonUniformFoveatedRendering = foveatedRendering && XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster);
  111. if (foveatedRendering)
  112. {
  113. if (nonUniformFoveatedRendering)
  114. // This is a screen-space pass, make sure foveated rendering is disabled for non-uniform renders
  115. cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Disabled);
  116. else
  117. cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Enabled);
  118. }
  119. #endif
  120. // Draw fullscreen quad
  121. cmd.DrawProcedural(Matrix4x4.identity, cameraMaterial, 0, MeshTopology.Triangles, 3, 1);
  122. #if ENABLE_VR && ENABLE_XR_MODULE
  123. if (foveatedRendering && !nonUniformFoveatedRendering)
  124. cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Disabled);
  125. #endif
  126. }
  127. private static void DrawObjectMotionVectors(RasterCommandBuffer cmd, XRPass xr, ref RendererList rendererList)
  128. {
  129. #if ENABLE_VR && ENABLE_XR_MODULE
  130. bool foveatedRendering = xr.supportsFoveatedRendering;
  131. if (foveatedRendering)
  132. // This is a geometry pass, enable foveated rendering (we need to disable it after)
  133. cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Enabled);
  134. #endif
  135. cmd.DrawRendererList(rendererList);
  136. #if ENABLE_VR && ENABLE_XR_MODULE
  137. if (foveatedRendering)
  138. cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Disabled);
  139. #endif
  140. }
  141. #endregion
  142. /// <summary>
  143. /// Shared pass data
  144. /// </summary>
  145. private class PassData
  146. {
  147. internal Camera camera;
  148. internal XRPass xr;
  149. internal TextureHandle motionVectorColor;
  150. internal TextureHandle motionVectorDepth;
  151. internal TextureHandle cameraDepth;
  152. internal Material cameraMaterial;
  153. internal RendererListHandle rendererListHdl;
  154. // Required for code sharing purpose between RG and non-RG.
  155. internal RendererList rendererList;
  156. }
  157. /// <summary>
  158. /// Initialize the shared pass data.
  159. /// </summary>
  160. /// <param name="passData"></param>
  161. private void InitPassData(ref PassData passData, UniversalCameraData cameraData)
  162. {
  163. passData.camera = cameraData.camera;
  164. passData.xr = cameraData.xr;
  165. passData.cameraMaterial = m_CameraMaterial;
  166. }
  167. private void InitRendererLists(ref PassData passData, ref CullingResults cullResults, bool supportsDynamicBatching, ScriptableRenderContext context, RenderGraph renderGraph, bool useRenderGraph)
  168. {
  169. var drawingSettings = GetDrawingSettings(passData.camera, supportsDynamicBatching);
  170. var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
  171. if (useRenderGraph)
  172. RenderingUtils.CreateRendererListWithRenderStateBlock(renderGraph, ref cullResults, drawingSettings, m_FilteringSettings, renderStateBlock, ref passData.rendererListHdl);
  173. else
  174. RenderingUtils.CreateRendererListWithRenderStateBlock(context, ref cullResults, drawingSettings, m_FilteringSettings, renderStateBlock, ref passData.rendererList);
  175. }
  176. internal void Render(RenderGraph renderGraph, ContextContainer frameData, TextureHandle cameraDepthTexture, TextureHandle motionVectorColor, TextureHandle motionVectorDepth)
  177. {
  178. UniversalRenderingData renderingData = frameData.Get<UniversalRenderingData>();
  179. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  180. using (var builder = renderGraph.AddRasterRenderPass<PassData>(profilingSampler == null ? "" : profilingSampler.name, out var passData, profilingSampler))
  181. {
  182. builder.UseAllGlobalTextures(true);
  183. // TODO RENDERGRAPH: culling? force culling off for testing
  184. builder.AllowPassCulling(false);
  185. builder.AllowGlobalStateModification(true);
  186. if (cameraData.xr.enabled)
  187. builder.EnableFoveatedRasterization(cameraData.xr.supportsFoveatedRendering && cameraData.xrUniversal.canFoveateIntermediatePasses);
  188. passData.motionVectorColor = motionVectorColor;
  189. builder.SetRenderAttachment(motionVectorColor, 0, AccessFlags.Write);
  190. passData.motionVectorDepth = motionVectorDepth;
  191. builder.SetRenderAttachmentDepth(motionVectorDepth, AccessFlags.Write);
  192. InitPassData(ref passData, cameraData);
  193. passData.cameraDepth = cameraDepthTexture;
  194. builder.UseTexture(cameraDepthTexture, AccessFlags.Read);
  195. InitRendererLists(ref passData, ref renderingData.cullResults, renderingData.supportsDynamicBatching,
  196. default(ScriptableRenderContext), renderGraph, true);
  197. builder.UseRendererList(passData.rendererListHdl);
  198. if (motionVectorColor.IsValid())
  199. builder.SetGlobalTextureAfterPass(motionVectorColor, Shader.PropertyToID(k_MotionVectorTextureName));
  200. if (motionVectorDepth.IsValid())
  201. builder.SetGlobalTextureAfterPass(motionVectorDepth, Shader.PropertyToID(k_MotionVectorDepthTextureName));
  202. builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
  203. {
  204. if (data.cameraMaterial != null)
  205. data.cameraMaterial.SetTexture(s_CameraDepthTextureID, data.cameraDepth);
  206. ExecutePass(context.cmd, data, data.rendererListHdl);
  207. });
  208. }
  209. }
  210. // Global motion vector matrix setup pass.
  211. // Used for MotionVector passes and also read in VFX early compute shader
  212. public class MotionMatrixPassData
  213. {
  214. public MotionVectorsPersistentData motionData;
  215. public XRPass xr;
  216. };
  217. internal static void SetMotionVectorGlobalMatrices(CommandBuffer cmd, UniversalCameraData cameraData)
  218. {
  219. if (cameraData.camera.TryGetComponent<UniversalAdditionalCameraData>(out var additionalCameraData))
  220. {
  221. additionalCameraData.motionVectorsPersistentData?.SetGlobalMotionMatrices(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData.xr);
  222. }
  223. }
  224. internal static void SetRenderGraphMotionVectorGlobalMatrices(RenderGraph renderGraph, UniversalCameraData cameraData)
  225. {
  226. if (cameraData.camera.TryGetComponent<UniversalAdditionalCameraData>(out var additionalCameraData))
  227. {
  228. using (var builder = renderGraph.AddRasterRenderPass<MotionMatrixPassData>(s_SetMotionMatrixProfilingSampler.name, out var passData, s_SetMotionMatrixProfilingSampler))
  229. {
  230. passData.motionData = additionalCameraData.motionVectorsPersistentData;
  231. passData.xr = cameraData.xr;
  232. builder.AllowPassCulling(false);
  233. builder.AllowGlobalStateModification(true);
  234. builder.SetRenderFunc(static (MotionMatrixPassData data, RasterGraphContext context) =>
  235. {
  236. data.motionData.SetGlobalMotionMatrices(context.cmd, data.xr);
  237. });
  238. }
  239. }
  240. }
  241. }
  242. }