From 817e328e977ec000fc1990da57d814af314beeb1 Mon Sep 17 00:00:00 2001 From: Manuele Bonanno Date: Thu, 21 Oct 2021 11:25:26 +0200 Subject: [PATCH] removing unnecessary depth copy pass and bind the scene depth directly for the post processing pass --- .../Runtime/Passes/PostProcessPass.cs | 16 ++++++++++- .../Runtime/UniversalRenderer.cs | 28 +++++++++++-------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/com.unity.render-pipelines.universal/Runtime/Passes/PostProcessPass.cs b/com.unity.render-pipelines.universal/Runtime/Passes/PostProcessPass.cs index e579c5cedf8..e6854c3382d 100644 --- a/com.unity.render-pipelines.universal/Runtime/Passes/PostProcessPass.cs +++ b/com.unity.render-pipelines.universal/Runtime/Passes/PostProcessPass.cs @@ -24,6 +24,7 @@ public class PostProcessPass : ScriptableRenderPass RenderTargetIdentifier m_Source; RenderTargetHandle m_Destination; RenderTargetHandle m_Depth; + RenderTargetHandle m_CameraDepthTexture; // m_DepthTexture from UniversalRenderer instance, needed if we need to restore "_CameraDepthTexture" binding to its original resource RenderTargetHandle m_InternalLut; const string k_RenderPostProcessingTag = "Render PostProcessing Effects"; @@ -86,6 +87,9 @@ public class PostProcessPass : ScriptableRenderPass // Renderer is using swapbuffer system bool m_UseSwapBuffer; + // When true, PostProcessPass will use depth information from main geometry render pass' depth texture + bool m_UseDepthTextureFromMainPass; + Material m_BlitMaterial; public PostProcessPass(RenderPassEvent evt, PostProcessData data, Material blitMaterial) @@ -141,13 +145,14 @@ public PostProcessPass(RenderPassEvent evt, PostProcessData data, Material blitM public void Cleanup() => m_Materials.Cleanup(); - public void Setup(in RenderTextureDescriptor baseDescriptor, in RenderTargetHandle source, bool resolveToScreen, in RenderTargetHandle depth, in RenderTargetHandle internalLut, bool hasFinalPass, bool enableSRGBConversion) + public void Setup(in RenderTextureDescriptor baseDescriptor, in RenderTargetHandle source, bool resolveToScreen, bool useDepthTextureFromMainPass, in RenderTargetHandle depth, in RenderTargetHandle cameraDepthTexture, in RenderTargetHandle internalLut, bool hasFinalPass, bool enableSRGBConversion) { m_Descriptor = baseDescriptor; m_Descriptor.useMipMap = false; m_Descriptor.autoGenerateMips = false; m_Source = source.id; m_Depth = depth; + m_CameraDepthTexture = cameraDepthTexture; m_InternalLut = internalLut; m_IsFinalPass = false; m_HasFinalPass = hasFinalPass; @@ -155,6 +160,7 @@ public void Setup(in RenderTextureDescriptor baseDescriptor, in RenderTargetHand m_ResolveToScreen = resolveToScreen; m_Destination = RenderTargetHandle.CameraTarget; m_UseSwapBuffer = true; + m_UseDepthTextureFromMainPass = useDepthTextureFromMainPass; } public void Setup(in RenderTextureDescriptor baseDescriptor, in RenderTargetHandle source, RenderTargetHandle destination, in RenderTargetHandle depth, in RenderTargetHandle internalLut, bool hasFinalPass, bool enableSRGBConversion) @@ -266,7 +272,15 @@ public override void Execute(ScriptableRenderContext context, ref RenderingData var cmd = CommandBufferPool.Get(); using (new ProfilingScope(cmd, m_ProfilingRenderPostProcessing)) { + // m_Depth is the main geometry pass' depth buffer. If condition is true, we bind this depth buffer to _CameraDepthTexture shader binding resource + if (m_UseDepthTextureFromMainPass) + cmd.SetGlobalTexture("_CameraDepthTexture", m_Depth.Identifier()); + Render(cmd, ref renderingData); + + // Restore the _CameraDepthTexture binding to its original bound resource + if (m_UseDepthTextureFromMainPass) + cmd.SetGlobalTexture("_CameraDepthTexture", m_CameraDepthTexture.Identifier()); } context.ExecuteCommandBuffer(cmd); diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs index cc3d4f00313..2cfa266fecb 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs @@ -519,6 +519,12 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re createColorTexture = createDepthTexture; } + bool requiresDepthCopyPass = !requiresDepthPrepass + && requiresDepthTexture + && createDepthTexture; + // Post process passes that require depth texture (Motion Blur / DoF) as shader read resource will need to access depth information from main geometry pass if there is no depth copy + // and depth pre-pass enqueued + bool postProcessingUseDepthTextureMainPass = !requiresDepthCopyPass && !requiresDepthPrepass && cameraHasPostProcessingWithDepth; // Configure all settings require to start a new camera stack (base camera only) if (cameraData.renderType == CameraRenderType.Base) { @@ -531,7 +537,7 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re // Doesn't create texture for Overlay cameras as they are already overlaying on top of created textures. if (intermediateRenderTexture) - CreateCameraRenderTarget(context, ref cameraTargetDescriptor, useDepthPriming); + CreateCameraRenderTarget(context, ref cameraTargetDescriptor, useDepthPriming, postProcessingUseDepthTextureMainPass); } else { @@ -541,9 +547,6 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re cameraData.renderer.useDepthPriming = useDepthPriming; - bool requiresDepthCopyPass = !requiresDepthPrepass - && (requiresDepthTexture || cameraHasPostProcessingWithDepth) - && createDepthTexture; bool copyColorPass = renderingData.cameraData.requiresOpaqueTexture || renderPassInputs.requiresColorTexture; if ((DebugHandler != null) && DebugHandler.IsActiveForCamera(ref cameraData)) @@ -684,13 +687,13 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re #endif // handle multisample depth resolve by setting the appropriate store actions if supported - if (requiresDepthCopyPass && cameraTargetDescriptor.msaaSamples > 1 && RenderingUtils.MultisampleDepthResolveSupported(useRenderPassEnabled)) + if ((requiresDepthCopyPass || postProcessingUseDepthTextureMainPass) && cameraTargetDescriptor.msaaSamples > 1 && RenderingUtils.MultisampleDepthResolveSupported(useRenderPassEnabled)) { bool isCopyDepthAfterTransparent = m_CopyDepthPass.renderPassEvent == RenderPassEvent.AfterRenderingTransparents; // we could StoreAndResolve when the depth copy is after opaque, but performance wise doing StoreAndResolve of depth targets is more expensive than a simple Store + following depth copy pass on Apple GPUs, // because of the extra resolve step. So, unless we are copying the depth after the transparent pass, just Store the depth target. - if (isCopyDepthAfterTransparent && !copyColorPass) + if ((isCopyDepthAfterTransparent || postProcessingUseDepthTextureMainPass) && !copyColorPass) { if (opaquePassDepthStoreAction == RenderBufferStoreAction.Store) opaquePassDepthStoreAction = RenderBufferStoreAction.StoreAndResolve; @@ -762,8 +765,9 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re RenderBufferStoreAction transparentPassColorStoreAction = cameraTargetDescriptor.msaaSamples > 1 && lastCameraInTheStack ? RenderBufferStoreAction.Resolve : RenderBufferStoreAction.Store; RenderBufferStoreAction transparentPassDepthStoreAction = RenderBufferStoreAction.DontCare; - // If CopyDepthPass pass event is scheduled on or after AfterRenderingTransparent, we will need to store the depth buffer or resolve (store for now until latest trunk has depth resolve support) it for MSAA case - if (requiresDepthCopyPass && m_CopyDepthPass.renderPassEvent >= RenderPassEvent.AfterRenderingTransparents) + // If CopyDepthPass pass event is scheduled on or after AfterRenderingTransparent, or if post processing passes will read from main geometry pass' depth texture, + // we will need to store the depth buffer or resolve it for MSAA case + if (postProcessingUseDepthTextureMainPass || (requiresDepthCopyPass && m_CopyDepthPass.renderPassEvent >= RenderPassEvent.AfterRenderingTransparents)) { transparentPassDepthStoreAction = RenderBufferStoreAction.Store; @@ -796,7 +800,7 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re { // if resolving to screen we need to be able to perform sRGBConvertion in post-processing if necessary bool doSRGBConvertion = resolvePostProcessingToCameraTarget; - postProcessPass.Setup(cameraTargetDescriptor, m_ActiveCameraColorAttachment, resolvePostProcessingToCameraTarget, m_ActiveCameraDepthAttachment, colorGradingLut, applyFinalPostProcessing, doSRGBConvertion); + postProcessPass.Setup(cameraTargetDescriptor, m_ActiveCameraColorAttachment, resolvePostProcessingToCameraTarget, postProcessingUseDepthTextureMainPass, m_ActiveCameraDepthAttachment, m_DepthTexture, colorGradingLut, applyFinalPostProcessing, doSRGBConvertion); EnqueuePass(postProcessPass); } @@ -850,7 +854,7 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re // stay in RT so we resume rendering on stack after post-processing else if (applyPostProcessing) { - postProcessPass.Setup(cameraTargetDescriptor, m_ActiveCameraColorAttachment, false, m_ActiveCameraDepthAttachment, colorGradingLut, false, false); + postProcessPass.Setup(cameraTargetDescriptor, m_ActiveCameraColorAttachment, false, postProcessingUseDepthTextureMainPass, m_ActiveCameraDepthAttachment, m_DepthTexture, colorGradingLut, false, false); EnqueuePass(postProcessPass); } @@ -1002,7 +1006,7 @@ private RenderPassInputSummary GetRenderPassInputs(ref RenderingData renderingDa return inputSummary; } - void CreateCameraRenderTarget(ScriptableRenderContext context, ref RenderTextureDescriptor descriptor, bool primedDepth) + void CreateCameraRenderTarget(ScriptableRenderContext context, ref RenderTextureDescriptor descriptor, bool primedDepth, bool postProcessingUseDepthTextureMainPass) { CommandBuffer cmd = CommandBufferPool.Get(); using (new ProfilingScope(null, Profiling.createCameraRenderTarget)) @@ -1035,7 +1039,7 @@ void CreateCameraRenderTarget(ScriptableRenderContext context, ref RenderTexture depthDescriptor.autoGenerateMips = false; depthDescriptor.bindMS = depthDescriptor.msaaSamples > 1 && !SystemInfo.supportsMultisampleAutoResolve && (SystemInfo.supportsMultisampledTextures != 0); - if (depthDescriptor.msaaSamples > 1 && RenderingUtils.MultisampleDepthResolveSupported(useRenderPassEnabled) && m_CopyDepthMode == CopyDepthMode.AfterTransparents) + if (depthDescriptor.msaaSamples > 1 && RenderingUtils.MultisampleDepthResolveSupported(useRenderPassEnabled) && (m_CopyDepthMode == CopyDepthMode.AfterTransparents || postProcessingUseDepthTextureMainPass)) depthDescriptor.bindMS = false; depthDescriptor.colorFormat = RenderTextureFormat.Depth;