diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index bdb8df8e12a..99a9213d17e 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -661,6 +661,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Raytracing: Removed the dynamic lightmap multicompile. - Raytracing: Remove the LOD cross fade multi compile for ray tracing. - Cookie are now supported in lightmaper. All lights casting cookie and baked will now include cookie influence. +- 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 22e1eb447a8..cda7b28d741 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 @@ -41,6 +43,20 @@ RW_TEXTURE2D(float4, _SsrDebugTexture); #endif +// 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 + #ifdef SSR_TRACE TEXTURE2D_X_UINT2( _StencilTexture); RW_TEXTURE2D_X(float2, _SsrHitPointTexture); @@ -104,7 +120,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 af2f4eff735..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 @@ -244,6 +244,7 @@ LightingOutput RenderDeferredLighting( RenderGraph renderGraph, class RenderSSRPassData { public RenderSSRParameters parameters; + public TextureHandle depthBuffer; public TextureHandle depthPyramid; public TextureHandle colorPyramid; public TextureHandle stencilBuffer; @@ -257,6 +258,7 @@ TextureHandle RenderSSR( RenderGraph renderGraph, HDCamera hdCamera, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer, + TextureHandle depthBuffer, TextureHandle depthPyramid, TextureHandle stencilBuffer, TextureHandle clearCoatMask) @@ -285,7 +287,8 @@ TextureHandle RenderSSR( RenderGraph renderGraph, var colorPyramid = renderGraph.ImportTexture(hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain)); - passData.parameters = PrepareSSRParameters(hdCamera, m_DepthBufferMipChainInfo); + 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); @@ -308,6 +311,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 379d8298beb..b0135edc0e7 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 a2a94da1d00..5cc12c92643 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -3878,6 +3878,7 @@ struct RenderSSRParameters public ComputeShader ssrCS; public int tracingKernel; public int reprojectionKernel; + public bool transparentSSR; public int width, height, viewCount; @@ -3887,7 +3888,7 @@ struct RenderSSRParameters public ShaderVariablesScreenSpaceReflection cb; } - RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMipChainInfo depthPyramid) + RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMipChainInfo depthPyramid, bool transparentSSR) { var volumeSettings = hdCamera.volumeStack.GetComponent(); var parameters = new RenderSSRParameters(); @@ -3895,6 +3896,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip parameters.ssrCS = m_ScreenSpaceReflectionsCS; parameters.tracingKernel = m_SsrTracingKernel; parameters.reprojectionKernel = m_SsrReprojectionKernel; + parameters.transparentSSR = transparentSSR; parameters.width = hdCamera.actualWidth; parameters.height = hdCamera.actualHeight; @@ -3927,6 +3929,7 @@ RenderSSRParameters PrepareSSRParameters(HDCamera hdCamera, in HDUtils.PackedMip } static void RenderSSR( in RenderSSRParameters parameters, + RTHandle depthTexture, RTHandle depthPyramid, RTHandle SsrHitPointTexture, RTHandle stencilBuffer, @@ -3941,6 +3944,12 @@ static void RenderSSR( in RenderSSRParameters parameters, using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SsrTracing))) { // 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); @@ -3960,6 +3969,9 @@ static void RenderSSR( in RenderSSRParameters parameters, ConstantBuffer.Push(cmd, parameters.cb, cs, HDShaderIDs._ShaderVariablesScreenSpaceReflection); 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))) @@ -3997,8 +4009,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, m_SharedRTManager.GetDepthBufferMipChainInfo()); - RenderSSR(parameters, m_SharedRTManager.GetDepthTexture(), m_SsrHitPointTexture, + var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), 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); @@ -4027,16 +4039,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, m_SharedRTManager.GetDepthBufferMipChainInfo()); - RenderSSR(parameters, m_SharedRTManager.GetDepthTexture(), m_SsrHitPointTexture, m_SharedRTManager.GetStencilBuffer(), TextureXR.GetBlackTexture(), previousColorPyramid, m_SsrLightingTexture, cmd, renderContext); + var parameters = PrepareSSRParameters(hdCamera, m_SharedRTManager.GetDepthBufferMipChainInfo(), 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)