Skip to content

Commit 1ff94e8

Browse files
authored
DoF: avoid calling GetDimensions for LoDs in the shader (#1256)
* DoF: Pass mipmap dimensions as shader constant * DoF: invalidate TAA history when switching modes
1 parent 297f9d6 commit 1ff94e8

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ private enum SMAAStage
144144

145145
HDRenderPipeline m_HDInstance;
146146

147+
bool m_IsDoFHisotoryValid = false;
148+
147149
void FillEmptyExposureTexture()
148150
{
149151
var tex = new Texture2D(1, 1, TextureFormat.RGHalf, false, true);
@@ -615,6 +617,12 @@ void PoolSource(ref RTHandle src, RTHandle dst)
615617
{
616618
using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DepthOfField)))
617619
{
620+
// If we switch DoF modes and the old one was not using TAA, make sure we invalidate the history
621+
if (taaEnabled && m_IsDoFHisotoryValid != m_DepthOfField.physicallyBased)
622+
{
623+
camera.resetPostProcessingHistory = true;
624+
}
625+
618626
var destination = m_Pool.Get(Vector2.one, m_ColorFormat);
619627
if (!m_DepthOfField.physicallyBased)
620628
DoDepthOfField(cmd, camera, source, destination, taaEnabled);
@@ -634,6 +642,8 @@ void PoolSource(ref RTHandle src, RTHandle dst)
634642
PoolSource(ref source, taaDestination);
635643
postDoFTAAEnabled = true;
636644
}
645+
646+
m_IsDoFHisotoryValid = (m_DepthOfField.physicallyBased && taaEnabled);
637647
}
638648
}
639649

@@ -2279,6 +2289,20 @@ void ReprojectCoCHistory(CommandBuffer cmd, HDCamera camera, bool useMips, ref R
22792289
fullresCoC = nextCoCTex;
22802290
}
22812291

2292+
static void GetMipMapDimensions(RTHandle texture, int lod, out int width, out int height)
2293+
{
2294+
width = texture.rt.width;
2295+
height = texture.rt.height;
2296+
2297+
for (int level = 0; level < lod; ++level)
2298+
{
2299+
// Note: When the texture/mip size is an odd number, the size of the next level is rounded down.
2300+
// That's why we cannot find the actual size by doing (size >> lod).
2301+
width /= 2;
2302+
height /= 2;
2303+
}
2304+
}
2305+
22822306
#endregion
22832307

22842308
#region Depth Of Field (Physically based)
@@ -2375,8 +2399,12 @@ void DoPhysicallyBasedDepthOfField(CommandBuffer cmd, HDCamera camera, RTHandle
23752399

23762400
kernel = cs.FindKernel("KMain");
23772401
float sampleCount = Mathf.Max(m_DepthOfField.nearSampleCount, m_DepthOfField.farSampleCount);
2378-
float mipLevel = Mathf.Ceil(Mathf.Log(cocLimit, 2));
2379-
cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, new Vector4(sampleCount, cocLimit, mipLevel, 0.0f));
2402+
2403+
// We only have up to 6 mip levels
2404+
float mipLevel = Mathf.Min(6, Mathf.Ceil(Mathf.Log(cocLimit, 2)));
2405+
GetMipMapDimensions(fullresCoC, (int)mipLevel, out var mipMapWidth, out var mipMapHeight);
2406+
cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, new Vector4(sampleCount, cocLimit, 0.0f, 0.0f));
2407+
cmd.SetComputeVectorParam(cs, HDShaderIDs._Params2, new Vector4(mipLevel, mipMapWidth, mipMapHeight, 0.0f));
23802408
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source);
23812409
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputCoCTexture, fullresCoC);
23822410
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination);

com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/DoFGather.compute

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111

1212
CBUFFER_START(cb0)
1313
float4 _Params;
14+
float4 _Params2;
1415
CBUFFER_END
1516

1617
#define NumRings _Params.x
1718
#define MaxCoCRadius _Params.y
18-
#define MaxCoCMipLevel _Params.z
19+
#define MaxCoCMipLevel _Params2.x
20+
#define MaxCoCMipWidth _Params2.y
21+
#define MaxCoCMipHeight _Params2.z
1922

2023
// Input textures
2124
TEXTURE2D_X(_InputTexture);
@@ -86,20 +89,9 @@ float GetCoCMaxRadius(int2 positionSS)
8689
#ifndef ADAPTIVE_RADIUS
8790
return MaxCoCRadius;
8891
#else
89-
// We only have up to 6 mip levels
90-
int lod = min(6, MaxCoCMipLevel);
91-
92-
// TODO FIXME - (Seb) I added this patch for metal as it was causing a
93-
// Shader error in 'DoFGather': 'GetDimensions' : no matching 5 parameter intrinsic method;
94-
// But overall I am even not this if this call work on Metal.
95-
#if defined(SHADER_API_METAL)
96-
uint3 size;
97-
// Texture2D<float4>.GetDimensions(uint, out uint width, out uint height, out uint levels)
98-
_InputCoCTexture.GetDimensions(lod, size.x, size.y, size.z);
99-
#else
100-
uint4 size;
101-
_InputCoCTexture.GetDimensions(lod, size.x, size.y, size.z, size.w);
102-
#endif
92+
93+
int lod = MaxCoCMipLevel;
94+
uint2 size = float2(MaxCoCMipWidth, MaxCoCMipHeight);
10395

10496
// Take RTHandleScale into account and odd texture dimension sizes (it's not enough to do a positionSS >> lod)
10597
uint2 coords = positionSS * _ScreenSize.zw * size.xy * _RTHandleScale.xy;

0 commit comments

Comments
 (0)