Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -141,20 +145,22 @@ 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;
m_EnableSRGBConversionIfNeeded = enableSRGBConversion;
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)
Expand Down Expand Up @@ -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());
Comment on lines +275 to +283
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to improve depth binding in URP so we would unify the depth buffer and the shader resource with a single ID, similar to how we handle color? I feel otherwise this is quite confusing for user that would like to do the same thing. I guess this is because the depth resolve issues and the fact that we don't have secondary id?

}

context.ExecuteCommandBuffer(cmd);
Expand Down
28 changes: 16 additions & 12 deletions com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool postProcessingUseDepthTextureMainPass = !requiresDepthCopyPass && !requiresDepthPrepass && cameraHasPostProcessingWithDepth;
bool postProcessingUseDepthTextureMainPass = !requiresDepthCopyPass && cameraHasPostProcessingWithDepth;

requiresDepthPrepass is reduntant logic here. If you expand requiresDepthCopyPass the expression you get:

bool postProcessingUseDepthTExtureMainPass = (!requiresDepthPrepass && requiresDepthTexture && createDepthTexture) && !requiresDepthPrepass && cameraHasPostProcessingWithDepth;

// Configure all settings require to start a new camera stack (base camera only)
if (cameraData.renderType == CameraRenderType.Base)
{
Expand All @@ -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
{
Expand All @@ -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))
Expand Down Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking: you have in multiple places isCopyDEpthAfterTransparent || postProcessingUseDepthTextureMainPass maybe you could give have a variable with some meaning for this to improve readability. The logic of store actions is a little bit convoluted, but I guess the plan is to improve it with RenderGraph anyway, so no big deal.

{
if (opaquePassDepthStoreAction == RenderBufferStoreAction.Store)
opaquePassDepthStoreAction = RenderBufferStoreAction.StoreAndResolve;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
Expand Down