From fb10832bc3d70e8887868ba8f6932621c64a355f Mon Sep 17 00:00:00 2001 From: Anis Date: Thu, 26 Mar 2020 17:53:50 +0100 Subject: [PATCH 1/3] - Avoid building the mip chain a second time for SSR for transparent objects. --- .../CHANGELOG.md | 1 + .../ScreenSpaceReflections.compute | 13 ++++++++++ .../HDRenderPipeline.LightLoop.cs | 6 ++++- .../HDRenderPipeline.RenderGraph.cs | 1 + .../RenderPipeline/HDRenderPipeline.cs | 26 ++++++++++++------- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 2460fbaf995..b6600798e8c 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -598,6 +598,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Changed a few resources used by ray tracing shaders to be global resources (using register space1) for improved CPU performance. - All custom pass volumes are now executed for one injection point instead of the first one. - Hidden unsupported choice in emission in Materials +- Avoid building the mip chain a second time for SSR for transparent objects. ## [7.1.1] - 2019-09-05 diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index b5e1b7f4d39..2c171623521 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -8,6 +8,8 @@ #pragma kernel ScreenSpaceReflectionsTracing SSR_TRACE #pragma kernel ScreenSpaceReflectionsReprojection SSR_REPROJECT +#pragma multi_compile _ DEPTH_SOURCE_NOT_FROM_MIP_CHAIN + // Tweak parameters. // #define DEBUG #define SSR_TRACE_BEHIND_OBJECTS @@ -40,6 +42,12 @@ RW_TEXTURE2D(float4, _SsrDebugTexture); #endif +// Given that for transparent objects we do not trace in a depth buffer that contains them +// we need a seperate texture for the mip chain and for the depth source +#ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN +TEXTURE2D_X(_DepthTexture); +#endif + #ifdef SSR_TRACE TEXTURE2D_X_UINT2( _StencilTexture); RW_TEXTURE2D_X(float2, _SsrHitPointTexture); @@ -121,7 +129,12 @@ void ScreenSpaceReflectionsTracing(uint3 groupId : SV_GroupID, } float2 positionNDC = positionSS * _ScreenSize.zw + (0.5 * _ScreenSize.zw); // Should we precompute the half-texel bias? We seem to use it a lot. + +#ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN + float deviceDepth = LOAD_TEXTURE2D_X(_DepthTexture, positionSS).r; +#else float deviceDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, positionSS).r; +#endif bool killRay = deviceDepth == UNITY_RAW_FAR_CLIP_VALUE; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 16d9d518633..2db9c9744e2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -241,6 +241,7 @@ LightingOutput RenderDeferredLighting( RenderGraph renderGraph, class RenderSSRPassData { public RenderSSRParameters parameters; + public TextureHandle depthBuffer; public TextureHandle depthPyramid; public TextureHandle colorPyramid; public TextureHandle stencilBuffer; @@ -254,6 +255,7 @@ TextureHandle RenderSSR( RenderGraph renderGraph, HDCamera hdCamera, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer, + TextureHandle depthBuffer, TextureHandle depthPyramid, TextureHandle stencilBuffer, TextureHandle clearCoatMask) @@ -282,7 +284,8 @@ TextureHandle RenderSSR( RenderGraph renderGraph, var colorPyramid = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain)); - passData.parameters = PrepareSSRParameters(hdCamera); + passData.parameters = PrepareSSRParameters(hdCamera, true); + passData.depthBuffer = builder.ReadTexture(depthBuffer); passData.depthPyramid = builder.ReadTexture(depthPyramid); passData.colorPyramid = builder.ReadTexture(colorPyramid); passData.stencilBuffer = builder.ReadTexture(stencilBuffer); @@ -305,6 +308,7 @@ TextureHandle RenderSSR( RenderGraph renderGraph, { var res = context.resources; RenderSSR(data.parameters, + res.GetTexture(data.depthBuffer), res.GetTexture(data.depthPyramid), res.GetTexture(data.hitPointsTexture), res.GetTexture(data.stencilBuffer), diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs index 756dc4c2fec..1b74a464849 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs @@ -75,6 +75,7 @@ void ExecuteWithRenderGraph( RenderRequest renderRequest, hdCamera, prepassOutput.resolvedNormalBuffer, prepassOutput.resolvedMotionVectorsBuffer, + prepassOutput.depthBuffer, prepassOutput.depthPyramidTexture, prepassOutput.stencilBuffer, clearCoatMask); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index a4a1765e85e..56b64d82cf3 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -3750,6 +3750,7 @@ struct RenderSSRParameters public ComputeShader ssrCS; public int tracingKernel; public int reprojectionKernel; + public bool transparentSSR; public int width, height, viewCount; public int maxIteration; @@ -3769,7 +3770,7 @@ struct RenderSSRParameters public int colorPyramidMipCount; } - RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera) + RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, bool transparentSSR) { var volumeSettings = hdCamera.volumeStack.GetComponent(); var parameters = new RenderSSRParameters(); @@ -3777,6 +3778,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera) parameters.ssrCS = m_ScreenSpaceReflectionsCS; parameters.tracingKernel = m_SsrTracingKernel; parameters.reprojectionKernel = m_SsrReprojectionKernel; + parameters.transparentSSR = transparentSSR; parameters.width = hdCamera.actualWidth; parameters.height = hdCamera.actualHeight; @@ -3811,6 +3813,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera) } static void RenderSSR( in RenderSSRParameters parameters, + RTHandle depthTexture, RTHandle depthPyramid, RTHandle SsrHitPointTexture, RTHandle stencilBuffer, @@ -3836,6 +3839,12 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.SetComputeIntParam(cs, HDShaderIDs._SsrStencilBit, (int)StencilUsage.TraceReflectionRay); // cmd.SetComputeTextureParam(cs, kernel, "_SsrDebugTexture", m_SsrDebugTexture); + // Bind the non mip chain if we are rendering the transaprent version + if (parameters.transparentSSR) + { + CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", true); + cmd.SetComputeTextureParam(cs, parameters.tracingKernel, HDShaderIDs._DepthTexture, depthTexture); + } cmd.SetComputeTextureParam(cs, parameters.tracingKernel, HDShaderIDs._CameraDepthTexture, depthPyramid); cmd.SetComputeTextureParam(cs, parameters.tracingKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMask); cmd.SetComputeTextureParam(cs, parameters.tracingKernel, HDShaderIDs._SsrHitPointTexture, SsrHitPointTexture); @@ -3854,6 +3863,9 @@ static void RenderSSR( in RenderSSRParameters parameters, cmd.SetComputeBufferParam(cs, parameters.tracingKernel, HDShaderIDs._DepthPyramidMipLevelOffsets, parameters.offsetBufferData); cmd.DispatchCompute(cs, parameters.tracingKernel, HDUtils.DivRoundUp(parameters.width, 8), HDUtils.DivRoundUp(parameters.height, 8), parameters.viewCount); + + if (parameters.transparentSSR) + CoreUtils.SetKeyword(cmd, "DEPTH_SOURCE_NOT_FROM_MIP_CHAIN", false); } using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrReprojection))) @@ -3889,8 +3901,8 @@ void RenderSSR(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext ren // Evaluate the clear coat mask texture based on the lit shader mode RTHandle clearCoatMask = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? m_GbufferManager.GetBuffer(2) : TextureXR.GetBlackTexture(); - var parameters = PrepareSSRParameters(hdCamera); - RenderSSR(parameters, m_SharedRTManager.GetDepthTexture(), m_SsrHitPointTexture, + var parameters = PrepareSSRParameters(hdCamera, false); + RenderSSR(parameters, m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA)), clearCoatMask, previousColorPyramid, m_SsrLightingTexture, cmd, renderContext); @@ -3919,16 +3931,12 @@ void RenderSSRTransparent(HDCamera hdCamera, CommandBuffer cmd, ScriptableRender // Clear the SSR lighting buffer (not sure it is required) CoreUtils.SetRenderTarget(cmd, m_SsrLightingTexture, ClearFlag.Color, Color.clear); CoreUtils.SetRenderTarget(cmd, m_SsrHitPointTexture, ClearFlag.Color, Color.clear); - - // Invalid the depth pyramid and regenerate the depth pyramid - m_IsDepthBufferCopyValid = false; - GenerateDepthPyramid(hdCamera, cmd, FullScreenDebugMode.DepthPyramid); } // Evaluate the screen space reflection for the transparent pixels var previousColorPyramid = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain); - var parameters = PrepareSSRParameters(hdCamera); - RenderSSR(parameters, m_SharedRTManager.GetDepthTexture(), m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrLightingTexture, cmd, renderContext); + var parameters = PrepareSSRParameters(hdCamera, true); + RenderSSR(parameters, m_SharedRTManager.GetDepthStencilBuffer(), m_SharedRTManager.GetDepthTexture(), m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrLightingTexture, cmd, renderContext); // If color pyramid was not valid, we bind a black texture if (!hdCamera.colorPyramidHistoryIsValid) From 5d22450bf6b2a418c4691349ebc68e2925ac4302 Mon Sep 17 00:00:00 2001 From: sebastienlagarde Date: Sat, 18 Apr 2020 14:26:15 +0200 Subject: [PATCH 2/3] Update ScreenSpaceReflections.compute --- .../ScreenSpaceReflections.compute | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute index 2c171623521..9900226dc45 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/ScreenSpaceReflections.compute @@ -42,8 +42,16 @@ RW_TEXTURE2D(float4, _SsrDebugTexture); #endif -// Given that for transparent objects we do not trace in a depth buffer that contains them -// we need a seperate texture for the mip chain and for the depth source +// For opaque we do the following operation: +// - Render opaque object in depth buffer +// - Generate depth pyramid from opaque depth buffer +// - Trigger ray from position recover from depth pyramid and raymarch with depth pyramid +// For transparent reflection we chose to not regenerate a depth pyramid to save performance. So we have +// - Generate depth pyramid from opaque depth buffer +// - Trigger ray from position recover from depth buffer (use depth pyramid) and raymarch with depth pyramid +// - Render transparent object with reflection in depth buffer in transparent prepass +// - Trigger ray from position recover from new depth buffer and raymarch with opaque depth pyramid +// So we need a seperate texture for the mip chain and for the depth source when doing the transprent reflection #ifdef DEPTH_SOURCE_NOT_FROM_MIP_CHAIN TEXTURE2D_X(_DepthTexture); #endif From 80e30098cb4d0f7f90472e0e5f820c6c4b5d319c Mon Sep 17 00:00:00 2001 From: Sebastien Lagarde Date: Sat, 18 Apr 2020 14:48:23 +0200 Subject: [PATCH 3/3] fix merge issue --- .../Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index 03cae0f86dc..cbda6597b97 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -288,6 +288,7 @@ TextureHandle RenderSSR( RenderGraph renderGraph, var colorPyramid = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain)); passData.parameters = PrepareSSRParameters(hdCamera, m_DepthBufferMipChainInfo, true); + passData.depthBuffer = builder.ReadTexture(depthBuffer); passData.depthPyramid = builder.ReadTexture(depthPyramid); passData.colorPyramid = builder.ReadTexture(colorPyramid); passData.stencilBuffer = builder.ReadTexture(stencilBuffer);