From 9b721fc364a5103c775ad3bb8ab4a7808f881f4d Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Sat, 11 Jul 2020 15:12:53 +0200 Subject: [PATCH 1/2] DoF: Pass mipmap dimensions as shader constant --- .../PostProcessing/PostProcessSystem.cs | 22 +++++++++++++++++-- .../PostProcessing/Shaders/DoFGather.compute | 22 ++++++------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index ea923f258af..d4f028e3d20 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -2279,6 +2279,20 @@ void ReprojectCoCHistory(CommandBuffer cmd, HDCamera camera, bool useMips, ref R fullresCoC = nextCoCTex; } + static void GetMipMapDimensions(RTHandle texture, int lod, out int width, out int height) + { + width = texture.rt.width; + height = texture.rt.height; + + for (int level = 0; level < lod; ++level) + { + // Note: When the texture/mip size is an odd number, the size of the next level is rounded down. + // That's why we cannot find the actual size by doing (size >> lod). + width /= 2; + height /= 2; + } + } + #endregion #region Depth Of Field (Physically based) @@ -2375,8 +2389,12 @@ void DoPhysicallyBasedDepthOfField(CommandBuffer cmd, HDCamera camera, RTHandle kernel = cs.FindKernel("KMain"); float sampleCount = Mathf.Max(m_DepthOfField.nearSampleCount, m_DepthOfField.farSampleCount); - float mipLevel = Mathf.Ceil(Mathf.Log(cocLimit, 2)); - cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, new Vector4(sampleCount, cocLimit, mipLevel, 0.0f)); + + // We only have up to 6 mip levels + float mipLevel = Mathf.Min(6, Mathf.Ceil(Mathf.Log(cocLimit, 2))); + GetMipMapDimensions(fullresCoC, (int)mipLevel, out var mipMapWidth, out var mipMapHeight); + cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, new Vector4(sampleCount, cocLimit, 0.0f, 0.0f)); + cmd.SetComputeVectorParam(cs, HDShaderIDs._Params2, new Vector4(mipLevel, mipMapWidth, mipMapHeight, 0.0f)); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputCoCTexture, fullresCoC); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/DoFGather.compute b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/DoFGather.compute index 16ad4aaa67f..f8a19cd3c2c 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/DoFGather.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/DoFGather.compute @@ -11,11 +11,14 @@ CBUFFER_START(cb0) float4 _Params; +float4 _Params2; CBUFFER_END #define NumRings _Params.x #define MaxCoCRadius _Params.y -#define MaxCoCMipLevel _Params.z +#define MaxCoCMipLevel _Params2.x +#define MaxCoCMipWidth _Params2.y +#define MaxCoCMipHeight _Params2.z // Input textures TEXTURE2D_X(_InputTexture); @@ -86,20 +89,9 @@ float GetCoCMaxRadius(int2 positionSS) #ifndef ADAPTIVE_RADIUS return MaxCoCRadius; #else - // We only have up to 6 mip levels - int lod = min(6, MaxCoCMipLevel); - - // TODO FIXME - (Seb) I added this patch for metal as it was causing a - // Shader error in 'DoFGather': 'GetDimensions' : no matching 5 parameter intrinsic method; - // But overall I am even not this if this call work on Metal. -#if defined(SHADER_API_METAL) - uint3 size; - // Texture2D.GetDimensions(uint, out uint width, out uint height, out uint levels) - _InputCoCTexture.GetDimensions(lod, size.x, size.y, size.z); -#else - uint4 size; - _InputCoCTexture.GetDimensions(lod, size.x, size.y, size.z, size.w); -#endif + + int lod = MaxCoCMipLevel; + uint2 size = float2(MaxCoCMipWidth, MaxCoCMipHeight); // Take RTHandleScale into account and odd texture dimension sizes (it's not enough to do a positionSS >> lod) uint2 coords = positionSS * _ScreenSize.zw * size.xy * _RTHandleScale.xy; From b78814e631569b45374621110d5e306ae74a249b Mon Sep 17 00:00:00 2001 From: Pavlos Mavridis Date: Wed, 15 Jul 2020 01:04:30 +0200 Subject: [PATCH 2/2] DoF: invalidate TAA history when switching modes --- .../Runtime/PostProcessing/PostProcessSystem.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index d4f028e3d20..0a9b847a38d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -144,6 +144,8 @@ private enum SMAAStage HDRenderPipeline m_HDInstance; + bool m_IsDoFHisotoryValid = false; + void FillEmptyExposureTexture() { var tex = new Texture2D(1, 1, TextureFormat.RGHalf, false, true); @@ -615,6 +617,12 @@ void PoolSource(ref RTHandle src, RTHandle dst) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DepthOfField))) { + // If we switch DoF modes and the old one was not using TAA, make sure we invalidate the history + if (taaEnabled && m_IsDoFHisotoryValid != m_DepthOfField.physicallyBased) + { + camera.resetPostProcessingHistory = true; + } + var destination = m_Pool.Get(Vector2.one, m_ColorFormat); if (!m_DepthOfField.physicallyBased) DoDepthOfField(cmd, camera, source, destination, taaEnabled); @@ -634,6 +642,8 @@ void PoolSource(ref RTHandle src, RTHandle dst) PoolSource(ref source, taaDestination); postDoFTAAEnabled = true; } + + m_IsDoFHisotoryValid = (m_DepthOfField.physicallyBased && taaEnabled); } }