post processing
[WindSway-HDRP.git] / Library / PackageCache / com.unity.postprocessing@2.1.6 / PostProcessing / Shaders / Builtins / MultiScaleVOUpsample.compute
blob8b5b85818ca15d312427768eb9e2885bd141d1a5
1 //
2 // This is a modified version of the SSAO renderer from Microsoft's MiniEngine
3 // library. The copyright notice from the original version is included below.
4 //
5 // The original source code of MiniEngine is available on GitHub.
6 // https://github.com/Microsoft/DirectX-Graphics-Samples
7 //
9 //
10 // Copyright (c) Microsoft. All rights reserved.
11 // This code is licensed under the MIT License (MIT).
12 // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
13 // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
14 // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
15 // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
17 // Developed by Minigraph
19 // Author:  James Stanard
22 #pragma warning(disable : 3568)
23 #pragma exclude_renderers gles gles3 d3d11_9x
25 #pragma kernel MultiScaleVOUpSample                         MAIN=MultiScaleVOUpSample
26 #pragma kernel MultiScaleVOUpSample_invert                  MAIN=MultiScaleVOUpSample_invert                    INVERT
27 #pragma kernel MultiScaleVOUpSample_premin                  MAIN=MultiScaleVOUpSample_premin                    COMBINE_LOWER_RESOLUTIONS
28 #pragma kernel MultiScaleVOUpSample_blendout                MAIN=MultiScaleVOUpSample_blendout                  BLEND_WITH_HIGHER_RESOLUTION
29 #pragma kernel MultiScaleVOUpSample_premin_blendout         MAIN=MultiScaleVOUpSample_premin_blendout           COMBINE_LOWER_RESOLUTIONS BLEND_WITH_HIGHER_RESOLUTION
31 #pragma kernel MultiScaleVOUpSample_MSAA                    MAIN=MultiScaleVOUpSample_MSAA                      
32 #pragma kernel MultiScaleVOUpSample_MSAA_invert             MAIN=MultiScaleVOUpSample_MSAA_invert               MSAA INVERT
33 #pragma kernel MultiScaleVOUpSample_MSAA_premin             MAIN=MultiScaleVOUpSample_MSAA_premin               MSAA COMBINE_LOWER_RESOLUTIONS
34 #pragma kernel MultiScaleVOUpSample_MSAA_blendout           MAIN=MultiScaleVOUpSample_MSAA_blendout             MSAA BLEND_WITH_HIGHER_RESOLUTION
35 #pragma kernel MultiScaleVOUpSample_MSAA_premin_blendout    MAIN=MultiScaleVOUpSample_MSAA_premin_blendout      MSAA COMBINE_LOWER_RESOLUTIONS BLEND_WITH_HIGHER_RESOLUTION
37 #include "../StdLib.hlsl"
40 #ifdef MSAA
41     Texture2D<float2> LoResDB; SamplerState samplerLoResDB;
42     Texture2D<float2> HiResDB; SamplerState samplerHiResDB;
43     Texture2D<float2> LoResAO1; SamplerState samplerLoResAO1;
44     #ifdef COMBINE_LOWER_RESOLUTIONS
45     Texture2D<float2> LoResAO2; SamplerState samplerLoResAO2;
46     #endif
47     #ifdef BLEND_WITH_HIGHER_RESOLUTION
48     Texture2D<float2> HiResAO; SamplerState samplerHiResAO;
49     #endif
50     // Output textures
51     RWTexture2D<float2> AoResult;
53     // Shared memory
54     groupshared float2 DepthCache[256];
55     groupshared float2 AOCache1[256];
56     groupshared float2 AOCache2[256];
57 #else
58     // Input textures
59     Texture2D<float> LoResDB; SamplerState samplerLoResDB;
60     Texture2D<float> HiResDB; SamplerState samplerHiResDB;
61     Texture2D<float> LoResAO1; SamplerState samplerLoResAO1;
62     #ifdef COMBINE_LOWER_RESOLUTIONS
63     Texture2D<float> LoResAO2; SamplerState samplerLoResAO2;
64     #endif
65     #ifdef BLEND_WITH_HIGHER_RESOLUTION
66     Texture2D<float> HiResAO; SamplerState samplerHiResAO;
67     #endif
69     // Ouput textures
70     RWTexture2D<float> AoResult;
72     // Shared memory
73     groupshared float DepthCache[256];
74     groupshared float AOCache1[256];
75     groupshared float AOCache2[256];
77 #endif
79 CBUFFER_START(CB1)
80     float4 InvLowResolution;
81     float4 InvHighResolution;
82     float4 AdditionalParams;
83 CBUFFER_END
85 #define NoiseFilterStrength AdditionalParams.x
86 #define StepSize AdditionalParams.y
87 #define kBlurTolerance AdditionalParams.z
88 #define kUpsampleTolerance AdditionalParams.w
90 void PrefetchData(uint index, float2 uv)
92 #ifdef MSAA
93     float4 AO1_0 = LoResAO1.GatherRed(samplerLoResAO1, uv);
94     float4 AO1_1 = LoResAO1.GatherGreen(samplerLoResAO1, uv);
96 #ifdef COMBINE_LOWER_RESOLUTIONS
97     AO1_0 = min(AO1_0, LoResAO2.GatherRed(samplerLoResAO2, uv));
98     AO1_1 = min(AO1_1, LoResAO2.GatherGreen(samplerLoResAO2, uv));
99 #endif
101     AOCache1[index] = float2(AO1_0.w, AO1_1.w);
102     AOCache1[index + 1] = float2(AO1_0.z, AO1_1.z);
103     AOCache1[index + 16] = float2(AO1_0.x, AO1_1.x);
104     AOCache1[index + 17] = float2(AO1_0.y, AO1_1.y);
106     float4 ID_0 = 1.0 / LoResDB.GatherRed(samplerLoResDB, uv);
107     float4 ID_1 = 1.0 / LoResDB.GatherGreen(samplerLoResDB, uv);
108     DepthCache[index] = float2(ID_0.w, ID_1.w);
109     DepthCache[index + 1] = float2(ID_0.z, ID_1.z);
110     DepthCache[index + 16] = float2(ID_0.x, ID_1.x);
111     DepthCache[index + 17] = float2(ID_0.y, ID_1.y);
112 #else
113     float4 AO1 = LoResAO1.Gather(samplerLoResAO1, uv);
115 #ifdef COMBINE_LOWER_RESOLUTIONS
116     AO1 = min(AO1, LoResAO2.Gather(samplerLoResAO2, uv));
117 #endif
119     AOCache1[index] = AO1.w;
120     AOCache1[index + 1] = AO1.z;
121     AOCache1[index + 16] = AO1.x;
122     AOCache1[index + 17] = AO1.y;
124     float4 ID = 1.0 / LoResDB.Gather(samplerLoResDB, uv);
125     DepthCache[index] = ID.w;
126     DepthCache[index + 1] = ID.z;
127     DepthCache[index + 16] = ID.x;
128     DepthCache[index + 17] = ID.y;
129 #endif
132 float SmartBlur(float a, float b, float c, float d, float e, bool Left, bool Middle, bool Right)
134     b = Left | Middle ? b : c;
135     a = Left ? a : b;
136     d = Right | Middle ? d : c;
137     e = Right ? e : d;
138     return ((a + e) / 2.0 + b + c + d) / 4.0;
141 bool CompareDeltas(float d1, float d2, float l1, float l2)
143     float temp = d1 * d2 + StepSize;
144     return temp * temp > l1 * l2 * kBlurTolerance;
147 void BlurHorizontally(uint leftMostIndex)
149 #ifdef MSAA 
150     float2 a0 = AOCache1[leftMostIndex];
151     float2 a1 = AOCache1[leftMostIndex + 1];
152     float2 a2 = AOCache1[leftMostIndex + 2];
153     float2 a3 = AOCache1[leftMostIndex + 3];
154     float2 a4 = AOCache1[leftMostIndex + 4];
155     float2 a5 = AOCache1[leftMostIndex + 5];
156     float2 a6 = AOCache1[leftMostIndex + 6];
158     float2 d0 = DepthCache[leftMostIndex];
159     float2 d1 = DepthCache[leftMostIndex + 1];
160     float2 d2 = DepthCache[leftMostIndex + 2];
161     float2 d3 = DepthCache[leftMostIndex + 3];
162     float2 d4 = DepthCache[leftMostIndex + 4];
163     float2 d5 = DepthCache[leftMostIndex + 5];
164     float2 d6 = DepthCache[leftMostIndex + 6];
166     float2 d01 = d1 - d0;
167     float2 d12 = d2 - d1;
168     float2 d23 = d3 - d2;
169     float2 d34 = d4 - d3;
170     float2 d45 = d5 - d4;
171     float2 d56 = d6 - d5;
173     float2 l01 = d01 * d01 + StepSize;
174     float2 l12 = d12 * d12 + StepSize;
175     float2 l23 = d23 * d23 + StepSize;
176     float2 l34 = d34 * d34 + StepSize;
177     float2 l45 = d45 * d45 + StepSize;
178     float2 l56 = d56 * d56 + StepSize;
180     bool c02_0 = CompareDeltas(d01.x, d12.x, l01.x, l12.x);
181     bool c13_0 = CompareDeltas(d12.x, d23.x, l12.x, l23.x);
182     bool c24_0 = CompareDeltas(d23.x, d34.x, l23.x, l34.x);
183     bool c35_0 = CompareDeltas(d34.x, d45.x, l34.x, l45.x);
184     bool c46_0 = CompareDeltas(d45.x, d56.x, l45.x, l56.x);
186     bool c02_1 = CompareDeltas(d01.y, d12.y, l01.y, l12.y);
187     bool c13_1 = CompareDeltas(d12.y, d23.y, l12.y, l23.y);
188     bool c24_1 = CompareDeltas(d23.y, d34.y, l23.y, l34.y);
189     bool c35_1 = CompareDeltas(d34.y, d45.y, l34.y, l45.y);
190     bool c46_1 = CompareDeltas(d45.y, d56.y, l45.y, l56.y);
192     AOCache2[leftMostIndex] = float2(SmartBlur(a0.x.x, a1.x, a2.x, a3.x, a4.x, c02_0, c13_0, c24_0), SmartBlur(a0.y, a1.y, a2.y, a3.y, a4.y, c02_1, c13_1, c24_1));
193     AOCache2[leftMostIndex + 1] = float2(SmartBlur(a1.x, a2.x, a3.x, a4.x, a5.x, c13_0, c24_0, c35_0), SmartBlur(a1.y, a2.y, a3.y, a4.y, a5.y, c13_1, c24_1, c35_1));
194     AOCache2[leftMostIndex + 2] = float2(SmartBlur(a2.x, a3.x, a4.x, a5.x, a6.x, c24_0, c35_0, c46_0), SmartBlur(a2.y, a3.y, a4.y, a5.y, a6.y, c24_1, c35_1, c46_1));
195 #else
196     float a0 = AOCache1[leftMostIndex];
197     float a1 = AOCache1[leftMostIndex + 1];
198     float a2 = AOCache1[leftMostIndex + 2];
199     float a3 = AOCache1[leftMostIndex + 3];
200     float a4 = AOCache1[leftMostIndex + 4];
201     float a5 = AOCache1[leftMostIndex + 5];
202     float a6 = AOCache1[leftMostIndex + 6];
204     float d0 = DepthCache[leftMostIndex];
205     float d1 = DepthCache[leftMostIndex + 1];
206     float d2 = DepthCache[leftMostIndex + 2];
207     float d3 = DepthCache[leftMostIndex + 3];
208     float d4 = DepthCache[leftMostIndex + 4];
209     float d5 = DepthCache[leftMostIndex + 5];
210     float d6 = DepthCache[leftMostIndex + 6];
212     float d01 = d1 - d0;
213     float d12 = d2 - d1;
214     float d23 = d3 - d2;
215     float d34 = d4 - d3;
216     float d45 = d5 - d4;
217     float d56 = d6 - d5;
219     float l01 = d01 * d01 + StepSize;
220     float l12 = d12 * d12 + StepSize;
221     float l23 = d23 * d23 + StepSize;
222     float l34 = d34 * d34 + StepSize;
223     float l45 = d45 * d45 + StepSize;
224     float l56 = d56 * d56 + StepSize;
226     bool c02 = CompareDeltas(d01, d12, l01, l12);
227     bool c13 = CompareDeltas(d12, d23, l12, l23);
228     bool c24 = CompareDeltas(d23, d34, l23, l34);
229     bool c35 = CompareDeltas(d34, d45, l34, l45);
230     bool c46 = CompareDeltas(d45, d56, l45, l56);
232     AOCache2[leftMostIndex] = SmartBlur(a0, a1, a2, a3, a4, c02, c13, c24);
233     AOCache2[leftMostIndex + 1] = SmartBlur(a1, a2, a3, a4, a5, c13, c24, c35);
234     AOCache2[leftMostIndex + 2] = SmartBlur(a2, a3, a4, a5, a6, c24, c35, c46);
235 #endif
238 void BlurVertically(uint topMostIndex)
240 #ifdef MSAA
241     float2 a0 = AOCache2[topMostIndex];
242     float2 a1 = AOCache2[topMostIndex + 16];
243     float2 a2 = AOCache2[topMostIndex + 32];
244     float2 a3 = AOCache2[topMostIndex + 48];
245     float2 a4 = AOCache2[topMostIndex + 64];
246     float2 a5 = AOCache2[topMostIndex + 80];
248     float2 d0 = DepthCache[topMostIndex + 2];
249     float2 d1 = DepthCache[topMostIndex + 18];
250     float2 d2 = DepthCache[topMostIndex + 34];
251     float2 d3 = DepthCache[topMostIndex + 50];
252     float2 d4 = DepthCache[topMostIndex + 66];
253     float2 d5 = DepthCache[topMostIndex + 82];
255     float2 d01 = d1 - d0;
256     float2 d12 = d2 - d1;
257     float2 d23 = d3 - d2;
258     float2 d34 = d4 - d3;
259     float2 d45 = d5 - d4;
261     float2 l01 = d01 * d01 + StepSize;
262     float2 l12 = d12 * d12 + StepSize;
263     float2 l23 = d23 * d23 + StepSize;
264     float2 l34 = d34 * d34 + StepSize;
265     float2 l45 = d45 * d45 + StepSize;
267     bool c02_0 = CompareDeltas(d01.x, d12.x, l01.x, l12.x);
268     bool c13_0 = CompareDeltas(d12.x, d23.x, l12.x, l23.x);
269     bool c24_0 = CompareDeltas(d23.x, d34.x, l23.x, l34.x);
270     bool c35_0 = CompareDeltas(d34.x, d45.x, l34.x, l45.x);
272     bool c02_1 = CompareDeltas(d01.y, d12.y, l01.y, l12.y);
273     bool c13_1 = CompareDeltas(d12.y, d23.y, l12.y, l23.y);
274     bool c24_1 = CompareDeltas(d23.y, d34.y, l23.y, l34.y);
275     bool c35_1 = CompareDeltas(d34.y, d45.y, l34.y, l45.y);
277     float2 aoResult1 = float2(SmartBlur(a0.x, a1.x, a2.x, a3.x, a4.x, c02_0, c13_0, c24_0), SmartBlur(a0.y, a1.y, a2.y, a3.y, a4.y, c02_1, c13_1, c24_1));
278     float2 aoResult2 = float2(SmartBlur(a1.x, a2.x, a3.x, a4.x, a5.x, c13_0, c24_0, c35_0), SmartBlur(a1.y, a2.y, a3.y, a4.y, a5.y, c13_1, c24_1, c35_1));
280     AOCache1[topMostIndex] = aoResult1;
281     AOCache1[topMostIndex + 16] = aoResult2;
282 #else
283     float a0 = AOCache2[topMostIndex];
284     float a1 = AOCache2[topMostIndex + 16];
285     float a2 = AOCache2[topMostIndex + 32];
286     float a3 = AOCache2[topMostIndex + 48];
287     float a4 = AOCache2[topMostIndex + 64];
288     float a5 = AOCache2[topMostIndex + 80];
290     float d0 = DepthCache[topMostIndex + 2];
291     float d1 = DepthCache[topMostIndex + 18];
292     float d2 = DepthCache[topMostIndex + 34];
293     float d3 = DepthCache[topMostIndex + 50];
294     float d4 = DepthCache[topMostIndex + 66];
295     float d5 = DepthCache[topMostIndex + 82];
297     float d01 = d1 - d0;
298     float d12 = d2 - d1;
299     float d23 = d3 - d2;
300     float d34 = d4 - d3;
301     float d45 = d5 - d4;
303     float l01 = d01 * d01 + StepSize;
304     float l12 = d12 * d12 + StepSize;
305     float l23 = d23 * d23 + StepSize;
306     float l34 = d34 * d34 + StepSize;
307     float l45 = d45 * d45 + StepSize;
309     bool c02 = CompareDeltas(d01, d12, l01, l12);
310     bool c13 = CompareDeltas(d12, d23, l12, l23);
311     bool c24 = CompareDeltas(d23, d34, l23, l34);
312     bool c35 = CompareDeltas(d34, d45, l34, l45);
314     float aoResult1 = SmartBlur(a0, a1, a2, a3, a4, c02, c13, c24);
315     float aoResult2 = SmartBlur(a1, a2, a3, a4, a5, c13, c24, c35);
317     AOCache1[topMostIndex] = aoResult1;
318     AOCache1[topMostIndex + 16] = aoResult2;
319 #endif
322 // We essentially want 5 weights:  4 for each low-res pixel and 1 to blend in when none of the 4 really
323 // match.  The filter strength is 1 / DeltaZTolerance.  So a tolerance of 0.01 would yield a strength of 100.
324 // Note that a perfect match of low to high depths would yield a weight of 10^6, completely superceding any
325 // noise filtering.  The noise filter is intended to soften the effects of shimmering when the high-res depth
326 // buffer has a lot of small holes in it causing the low-res depth buffer to inaccurately represent it.
327 float BilateralUpsample(float HiDepth, float HiAO, float4 LowDepths, float4 LowAO)
329     float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + kUpsampleTolerance);
330     float TotalWeight = dot(weights, 1) + NoiseFilterStrength;
331     float WeightedSum = dot(LowAO, weights) + NoiseFilterStrength;// * HiAO;
332     return HiAO * WeightedSum / TotalWeight;
335 #ifdef DISABLE_COMPUTE_SHADERS
337 TRIVIAL_COMPUTE_KERNEL(MAIN)
339 #else
341 [numthreads(8, 8, 1)]
342 void MAIN(uint3 Gid : SV_GroupID, uint GI : SV_GroupIndex, uint3 GTid : SV_GroupThreadID, uint3 DTid : SV_DispatchThreadID)
344     //
345     // Load 4 pixels per thread into LDS to fill the 16x16 LDS cache with depth and AO
346     //
347     PrefetchData(GTid.x << 1 | GTid.y << 5, int2(DTid.xy + GTid.xy - 2) * InvLowResolution.xy);
348     GroupMemoryBarrierWithGroupSync();
350     // Goal:  End up with a 9x9 patch that is blurred so we can upsample.  Blur radius is 2 pixels, so start with 13x13 area.
352     //
353     // Horizontally blur the pixels.    13x13 -> 9x13
354     //
355     if (GI < 39)
356         BlurHorizontally((GI / 3) * 16 + (GI % 3) * 3);
357     GroupMemoryBarrierWithGroupSync();
359     //
360     // Vertically blur the pixels.              9x13 -> 9x9
361     //
362     if (GI < 45)
363         BlurVertically((GI / 9) * 32 + GI % 9);
364     GroupMemoryBarrierWithGroupSync();
366     //
367     // Bilateral upsample
368     //
369     uint Idx0 = GTid.x + GTid.y * 16;
370     #ifdef MSAA
371     float4 LoSSAOs0 = float4(AOCache1[Idx0 + 16].x, AOCache1[Idx0 + 17].x, AOCache1[Idx0 + 1].x, AOCache1[Idx0].x);
372     float4 LoSSAOs1 = float4(AOCache1[Idx0 + 16].y, AOCache1[Idx0 + 17].y, AOCache1[Idx0 + 1].y, AOCache1[Idx0].y);
373     #else
374     float4 LoSSAOs = float4(AOCache1[Idx0 + 16], AOCache1[Idx0 + 17], AOCache1[Idx0 + 1], AOCache1[Idx0]);
375     #endif
377     // We work on a quad of pixels at once because then we can gather 4 each of high and low-res depth values
378     float2 UV0 = DTid.xy * InvLowResolution.xy;
379     float2 UV1 = DTid.xy * 2 * InvHighResolution.xy;
381 #ifdef MSAA
382     #ifdef BLEND_WITH_HIGHER_RESOLUTION
383         float4 HiSSAOs0 = HiResAO.GatherRed(samplerHiResAO, UV1);
384         float4 HiSSAOs1 = HiResAO.GatherGreen(samplerHiResAO, UV1);
385     #else
386         float4 HiSSAOs0 = 1.0;
387         float4 HiSSAOs1 = 1.0;
388     #endif
389     float4 LoDepths0 = LoResDB.GatherRed(samplerLoResDB, UV0);
390     float4 LoDepths1 = LoResDB.GatherGreen(samplerLoResDB, UV0);
391     float4 HiDepths0 = HiResDB.GatherRed(samplerHiResDB, UV1);
392     float4 HiDepths1 = HiResDB.GatherGreen(samplerHiResDB, UV1);
394     int2 OutST = DTid.xy << 1;
396     #ifdef INVERT
397         AoResult[OutST + int2(-1,  0)] = float2(1.0 - BilateralUpsample(HiDepths0.x, HiSSAOs0.x, LoDepths0.xyzw, LoSSAOs0.xyzw), 1.0 - BilateralUpsample(HiDepths1.x, HiSSAOs1.x, LoDepths1.xyzw, LoSSAOs1.xyzw));
398         AoResult[OutST + int2( 0,  0)] = float2(1.0 - BilateralUpsample(HiDepths0.y, HiSSAOs0.y, LoDepths0.yzwx, LoSSAOs0.yzwx), 1.0 - BilateralUpsample(HiDepths1.y, HiSSAOs1.y, LoDepths1.yzwx, LoSSAOs1.yzwx));
399         AoResult[OutST + int2( 0, -1)] = float2(1.0 - BilateralUpsample(HiDepths0.z, HiSSAOs0.z, LoDepths0.zwxy, LoSSAOs0.zwxy), 1.0 - BilateralUpsample(HiDepths1.z, HiSSAOs1.z, LoDepths1.zwxy, LoSSAOs1.zwxy));
400         AoResult[OutST + int2(-1, -1)] = float2(1.0 - BilateralUpsample(HiDepths0.w, HiSSAOs0.w, LoDepths0.wxyz, LoSSAOs0.wxyz), 1.0 - BilateralUpsample(HiDepths1.w, HiSSAOs1.w, LoDepths1.wxyz, LoSSAOs1.wxyz));
401     #else
402         AoResult[OutST + int2(-1,  0)] = float2(BilateralUpsample(HiDepths0.x, HiSSAOs0.x, LoDepths0.xyzw, LoSSAOs0.xyzw), BilateralUpsample(HiDepths1.x, HiSSAOs1.x, LoDepths1.xyzw, LoSSAOs1.xyzw));
403         AoResult[OutST + int2( 0,  0)] = float2(BilateralUpsample(HiDepths0.y, HiSSAOs0.y, LoDepths0.yzwx, LoSSAOs0.yzwx), BilateralUpsample(HiDepths1.y, HiSSAOs1.y, LoDepths1.yzwx, LoSSAOs1.yzwx));
404         AoResult[OutST + int2( 0, -1)] = float2(BilateralUpsample(HiDepths0.z, HiSSAOs0.z, LoDepths0.zwxy, LoSSAOs0.zwxy), BilateralUpsample(HiDepths1.z, HiSSAOs1.z, LoDepths1.zwxy, LoSSAOs1.zwxy));
405         AoResult[OutST + int2(-1, -1)] = float2(BilateralUpsample(HiDepths0.w, HiSSAOs0.w, LoDepths0.wxyz, LoSSAOs0.wxyz),BilateralUpsample(HiDepths1.w, HiSSAOs1.w, LoDepths1.wxyz, LoSSAOs1.wxyz));
406     #endif
407 #else
408     #ifdef BLEND_WITH_HIGHER_RESOLUTION
409         float4 HiSSAOs = HiResAO.Gather(samplerHiResAO, UV1);
410     #else
411         float4 HiSSAOs = 1.0;
412     #endif
413     float4 LoDepths = LoResDB.Gather(samplerLoResDB, UV0);
414     float4 HiDepths = HiResDB.Gather(samplerHiResDB, UV1);
416     int2 OutST = DTid.xy << 1;
418     #ifdef INVERT
419         AoResult[OutST + int2(-1,  0)] = 1.0 - BilateralUpsample(HiDepths.x, HiSSAOs.x, LoDepths.xyzw, LoSSAOs.xyzw);
420         AoResult[OutST + int2( 0,  0)] = 1.0 - BilateralUpsample(HiDepths.y, HiSSAOs.y, LoDepths.yzwx, LoSSAOs.yzwx);
421         AoResult[OutST + int2( 0, -1)] = 1.0 - BilateralUpsample(HiDepths.z, HiSSAOs.z, LoDepths.zwxy, LoSSAOs.zwxy);
422         AoResult[OutST + int2(-1, -1)] = 1.0 - BilateralUpsample(HiDepths.w, HiSSAOs.w, LoDepths.wxyz, LoSSAOs.wxyz);
423     #else
424         AoResult[OutST + int2(-1,  0)] = BilateralUpsample(HiDepths.x, HiSSAOs.x, LoDepths.xyzw, LoSSAOs.xyzw);
425         AoResult[OutST + int2( 0,  0)] = BilateralUpsample(HiDepths.y, HiSSAOs.y, LoDepths.yzwx, LoSSAOs.yzwx);
426         AoResult[OutST + int2( 0, -1)] = BilateralUpsample(HiDepths.z, HiSSAOs.z, LoDepths.zwxy, LoSSAOs.zwxy);
427         AoResult[OutST + int2(-1, -1)] = BilateralUpsample(HiDepths.w, HiSSAOs.w, LoDepths.wxyz, LoSSAOs.wxyz);
428     #endif
429 #endif
432 #endif // DISABLE_COMPUTE_SHADERS