123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- using System;
- using Unity.Collections;
- using UnityEngine.Experimental.Rendering;
- using UnityEngine.Rendering.RenderGraphModule;
-
- namespace UnityEngine.Rendering.Universal
- {
- sealed class MotionVectorRenderPass : ScriptableRenderPass
- {
- #region Fields
- internal const string k_MotionVectorTextureName = "_MotionVectorTexture";
- internal const string k_MotionVectorDepthTextureName = "_MotionVectorDepthTexture";
-
- internal const GraphicsFormat k_TargetFormat = GraphicsFormat.R16G16_SFloat;
-
- public const string k_MotionVectorsLightModeTag = "MotionVectors";
- static readonly string[] s_ShaderTags = new string[] { k_MotionVectorsLightModeTag };
-
- static readonly int s_CameraDepthTextureID = Shader.PropertyToID("_CameraDepthTexture");
- static readonly ProfilingSampler s_SetMotionMatrixProfilingSampler = new ProfilingSampler("Set Motion Vector Global Matrices");
-
- RTHandle m_Color;
- RTHandle m_Depth;
- readonly Material m_CameraMaterial;
- readonly FilteringSettings m_FilteringSettings;
-
- private PassData m_PassData;
- #endregion
-
- #region Constructors
- internal MotionVectorRenderPass(RenderPassEvent evt, Material cameraMaterial, LayerMask opaqueLayerMask)
- {
- renderPassEvent = evt;
- m_CameraMaterial = cameraMaterial;
- m_FilteringSettings = new FilteringSettings(RenderQueueRange.opaque,opaqueLayerMask);
- m_PassData = new PassData();
- base.profilingSampler = ProfilingSampler.Get(URPProfileId.DrawMotionVectors);
-
- ConfigureInput(ScriptableRenderPassInput.Depth);
- }
-
- #endregion
-
- #region State
- internal void Setup(RTHandle color, RTHandle depth)
- {
- m_Color = color;
- m_Depth = depth;
- }
-
- [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
- public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
- {
- cmd.SetGlobalTexture(m_Color.name, m_Color.nameID);
- cmd.SetGlobalTexture(m_Depth.name, m_Depth.nameID);
-
- // Disable obsolete warning for internal usage
- #pragma warning disable CS0618
- ConfigureTarget(m_Color, m_Depth);
- ConfigureClear(ClearFlag.Color | ClearFlag.Depth, Color.black);
-
- // Can become a Store based on 'StoreActionsOptimization.Auto' and/or if a user RendererFeature is added.
- // We need to keep the MotionVecDepth in case of a user wants to extend the motion vectors
- // using a custom RendererFeature.
- ConfigureDepthStoreAction(RenderBufferStoreAction.DontCare);
- #pragma warning restore CS0618
- }
-
- #endregion
-
- #region Execution
- private static void ExecutePass(RasterCommandBuffer cmd, PassData passData, RendererList rendererList)
- {
- var cameraMaterial = passData.cameraMaterial;
-
- if (cameraMaterial == null)
- return;
-
- // Get data
- Camera camera = passData.camera;
-
- // Never draw in Preview
- if (camera.cameraType == CameraType.Preview)
- return;
-
- // These flags are still required in SRP or the engine won't compute previous model matrices...
- // If the flag hasn't been set yet on this camera, motion vectors will skip a frame.
- camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
-
- // TODO: add option to only draw either one?
- DrawCameraMotionVectors(cmd, passData.xr, cameraMaterial);
- DrawObjectMotionVectors(cmd, passData.xr, ref rendererList);
- }
-
- [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
- public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
- {
- ContextContainer frameData = renderingData.frameData;
- UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
- UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
-
- var cmd = CommandBufferHelpers.GetRasterCommandBuffer(renderingData.commandBuffer);
-
- // Profiling command
- using (new ProfilingScope(cmd,profilingSampler))
- {
- InitPassData(ref m_PassData, cameraData);
-
- InitRendererLists(ref m_PassData, ref universalRenderingData.cullResults, universalRenderingData.supportsDynamicBatching,
- context, default(RenderGraph), false);
-
- ExecutePass(cmd, m_PassData, m_PassData.rendererList);
- }
- }
-
- private static DrawingSettings GetDrawingSettings(Camera camera, bool supportsDynamicBatching)
- {
- var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque };
- var drawingSettings = new DrawingSettings(ShaderTagId.none, sortingSettings)
- {
- perObjectData = PerObjectData.MotionVectors,
- enableDynamicBatching = supportsDynamicBatching,
- enableInstancing = true,
- };
-
- for (int i = 0; i < s_ShaderTags.Length; ++i)
- {
- drawingSettings.SetShaderPassName(i, new ShaderTagId(s_ShaderTags[i]));
- }
-
- return drawingSettings;
- }
-
- // NOTE: depends on camera depth to reconstruct static geometry positions
- private static void DrawCameraMotionVectors(RasterCommandBuffer cmd, XRPass xr, Material cameraMaterial)
- {
- #if ENABLE_VR && ENABLE_XR_MODULE
- bool foveatedRendering = xr.supportsFoveatedRendering;
- bool nonUniformFoveatedRendering = foveatedRendering && XRSystem.foveatedRenderingCaps.HasFlag(FoveatedRenderingCaps.NonUniformRaster);
-
- if (foveatedRendering)
- {
- if (nonUniformFoveatedRendering)
- // This is a screen-space pass, make sure foveated rendering is disabled for non-uniform renders
- cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Disabled);
- else
- cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Enabled);
- }
- #endif
- // Draw fullscreen quad
- cmd.DrawProcedural(Matrix4x4.identity, cameraMaterial, 0, MeshTopology.Triangles, 3, 1);
-
- #if ENABLE_VR && ENABLE_XR_MODULE
- if (foveatedRendering && !nonUniformFoveatedRendering)
- cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Disabled);
- #endif
- }
-
- private static void DrawObjectMotionVectors(RasterCommandBuffer cmd, XRPass xr, ref RendererList rendererList)
- {
- #if ENABLE_VR && ENABLE_XR_MODULE
- bool foveatedRendering = xr.supportsFoveatedRendering;
- if (foveatedRendering)
- // This is a geometry pass, enable foveated rendering (we need to disable it after)
- cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Enabled);
- #endif
- cmd.DrawRendererList(rendererList);
-
- #if ENABLE_VR && ENABLE_XR_MODULE
- if (foveatedRendering)
- cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Disabled);
- #endif
- }
- #endregion
-
- /// <summary>
- /// Shared pass data
- /// </summary>
- private class PassData
- {
- internal Camera camera;
- internal XRPass xr;
-
- internal TextureHandle motionVectorColor;
- internal TextureHandle motionVectorDepth;
- internal TextureHandle cameraDepth;
- internal Material cameraMaterial;
- internal RendererListHandle rendererListHdl;
-
- // Required for code sharing purpose between RG and non-RG.
- internal RendererList rendererList;
- }
- /// <summary>
- /// Initialize the shared pass data.
- /// </summary>
- /// <param name="passData"></param>
- private void InitPassData(ref PassData passData, UniversalCameraData cameraData)
- {
- passData.camera = cameraData.camera;
- passData.xr = cameraData.xr;
-
- passData.cameraMaterial = m_CameraMaterial;
- }
-
- private void InitRendererLists(ref PassData passData, ref CullingResults cullResults, bool supportsDynamicBatching, ScriptableRenderContext context, RenderGraph renderGraph, bool useRenderGraph)
- {
- var drawingSettings = GetDrawingSettings(passData.camera, supportsDynamicBatching);
- var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
- if (useRenderGraph)
- RenderingUtils.CreateRendererListWithRenderStateBlock(renderGraph, ref cullResults, drawingSettings, m_FilteringSettings, renderStateBlock, ref passData.rendererListHdl);
- else
- RenderingUtils.CreateRendererListWithRenderStateBlock(context, ref cullResults, drawingSettings, m_FilteringSettings, renderStateBlock, ref passData.rendererList);
- }
-
- internal void Render(RenderGraph renderGraph, ContextContainer frameData, TextureHandle cameraDepthTexture, TextureHandle motionVectorColor, TextureHandle motionVectorDepth)
- {
- UniversalRenderingData renderingData = frameData.Get<UniversalRenderingData>();
- UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
-
- using (var builder = renderGraph.AddRasterRenderPass<PassData>(profilingSampler == null ? "" : profilingSampler.name, out var passData, profilingSampler))
- {
- builder.UseAllGlobalTextures(true);
-
- // TODO RENDERGRAPH: culling? force culling off for testing
- builder.AllowPassCulling(false);
- builder.AllowGlobalStateModification(true);
- if (cameraData.xr.enabled)
- builder.EnableFoveatedRasterization(cameraData.xr.supportsFoveatedRendering && cameraData.xrUniversal.canFoveateIntermediatePasses);
-
- passData.motionVectorColor = motionVectorColor;
- builder.SetRenderAttachment(motionVectorColor, 0, AccessFlags.Write);
- passData.motionVectorDepth = motionVectorDepth;
- builder.SetRenderAttachmentDepth(motionVectorDepth, AccessFlags.Write);
- InitPassData(ref passData, cameraData);
- passData.cameraDepth = cameraDepthTexture;
- builder.UseTexture(cameraDepthTexture, AccessFlags.Read);
-
- InitRendererLists(ref passData, ref renderingData.cullResults, renderingData.supportsDynamicBatching,
- default(ScriptableRenderContext), renderGraph, true);
- builder.UseRendererList(passData.rendererListHdl);
-
- if (motionVectorColor.IsValid())
- builder.SetGlobalTextureAfterPass(motionVectorColor, Shader.PropertyToID(k_MotionVectorTextureName));
- if (motionVectorDepth.IsValid())
- builder.SetGlobalTextureAfterPass(motionVectorDepth, Shader.PropertyToID(k_MotionVectorDepthTextureName));
-
- builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
- {
- if (data.cameraMaterial != null)
- data.cameraMaterial.SetTexture(s_CameraDepthTextureID, data.cameraDepth);
-
- ExecutePass(context.cmd, data, data.rendererListHdl);
- });
- }
- }
-
- // Global motion vector matrix setup pass.
- // Used for MotionVector passes and also read in VFX early compute shader
- public class MotionMatrixPassData
- {
- public MotionVectorsPersistentData motionData;
- public XRPass xr;
- };
-
- internal static void SetMotionVectorGlobalMatrices(CommandBuffer cmd, UniversalCameraData cameraData)
- {
- if (cameraData.camera.TryGetComponent<UniversalAdditionalCameraData>(out var additionalCameraData))
- {
- additionalCameraData.motionVectorsPersistentData?.SetGlobalMotionMatrices(CommandBufferHelpers.GetRasterCommandBuffer(cmd), cameraData.xr);
- }
- }
-
- internal static void SetRenderGraphMotionVectorGlobalMatrices(RenderGraph renderGraph, UniversalCameraData cameraData)
- {
- if (cameraData.camera.TryGetComponent<UniversalAdditionalCameraData>(out var additionalCameraData))
- {
- using (var builder = renderGraph.AddRasterRenderPass<MotionMatrixPassData>(s_SetMotionMatrixProfilingSampler.name, out var passData, s_SetMotionMatrixProfilingSampler))
- {
- passData.motionData = additionalCameraData.motionVectorsPersistentData;
- passData.xr = cameraData.xr;
-
- builder.AllowPassCulling(false);
- builder.AllowGlobalStateModification(true);
- builder.SetRenderFunc(static (MotionMatrixPassData data, RasterGraphContext context) =>
- {
- data.motionData.SetGlobalMotionMatrices(context.cmd, data.xr);
- });
- }
- }
- }
- }
- }
|