@@ -161,64 +161,60 @@ ProjectionDesc ComputeReprojection(float2 PrevPos, float CurrDepth)
161161 g_TextureCurrDepth.GetDimensions (DepthDim.x, DepthDim.y);
162162 if (!Desc.IsSuccess)
163163 {
164- float Disocclusion = 0.0 ;
165- const int SearchRadius = 1 ;
164+ float4 BestWeights = float4 (0.0 , 0.0 , 0.0 , 0.0 );
165+ int4 BestFetchCoords = int4 (0 , 0 , 0 , 0 );
166+ float BestTotalWeight = 0.0 ;
167+
168+ const int SearchRadius = 1 ;
169+ const float BestTotalWeightEarlyExitThreshold = 0.9 ;
166170 for (int y = -SearchRadius; y <= SearchRadius; y++)
167171 {
168172 for (int x = -SearchRadius; x <= SearchRadius; x++)
169173 {
170- float2 Location = PrevPos + float2 (x, y);
171- float PrevCameraZ = SampleCameraZFromDepthUC (g_TexturePrevDepth, DepthDim, Location, 0 , g_PrevCamera.mProj);
172- float Weight = ComputeDisocclusion (CurrCamZ, PrevCameraZ);
173- if (Weight > Disocclusion)
174+ float2 Location = PrevPos + float2 (x, y);
175+
176+ int4 FetchCoords;
177+ float4 Weights;
178+ GetBilinearSamplingInfoUC (Location, DepthDim, FetchCoords, Weights);
179+
180+ float PrevZ00 = DepthToCameraZ (LoadPrevDepth (FetchCoords.xy), g_PrevCamera.mProj);
181+ float PrevZ10 = DepthToCameraZ (LoadPrevDepth (FetchCoords.zy), g_PrevCamera.mProj);
182+ float PrevZ01 = DepthToCameraZ (LoadPrevDepth (FetchCoords.xw), g_PrevCamera.mProj);
183+ float PrevZ11 = DepthToCameraZ (LoadPrevDepth (FetchCoords.zw), g_PrevCamera.mProj);
184+
185+ Weights.x *= ComputeDisocclusion (CurrCamZ, PrevZ00) > (SSR_DISOCCLUSION_THRESHOLD / 2.0 ) ? 1.0 : 0.0 ;
186+ Weights.y *= ComputeDisocclusion (CurrCamZ, PrevZ10) > (SSR_DISOCCLUSION_THRESHOLD / 2.0 ) ? 1.0 : 0.0 ;
187+ Weights.z *= ComputeDisocclusion (CurrCamZ, PrevZ01) > (SSR_DISOCCLUSION_THRESHOLD / 2.0 ) ? 1.0 : 0.0 ;
188+ Weights.w *= ComputeDisocclusion (CurrCamZ, PrevZ11) > (SSR_DISOCCLUSION_THRESHOLD / 2.0 ) ? 1.0 : 0.0 ;
189+
190+ float TotalWeight = dot (Weights, float4 (1.0 , 1.0 , 1.0 , 1.0 ));
191+ if (TotalWeight > BestTotalWeight)
174192 {
175- Disocclusion = Weight;
176- Desc.PrevCoord = Location;
193+ BestTotalWeight = TotalWeight;
194+ BestWeights = Weights;
195+ BestFetchCoords = FetchCoords;
196+ Desc.PrevCoord = Location;
197+
198+ if (BestTotalWeight > BestTotalWeightEarlyExitThreshold)
199+ break ;
177200 }
178201 }
202+
203+ if (BestTotalWeight > BestTotalWeightEarlyExitThreshold)
204+ break ;
179205 }
180206
181- Desc.IsSuccess = Disocclusion > SSR_DISOCCLUSION_THRESHOLD;
182- Desc.Color = SamplePrevRadianceLinear (Desc.PrevCoord);
183- }
184-
185- if (!Desc.IsSuccess)
186- {
187- float2 PrevCoord = Desc.PrevCoord - float2 (0.5 , 0.5 );
188- float2 PrevCoord00 = floor (PrevCoord);
189- int2 PrevCoord00i = int2 (PrevCoord00);
190- float x = PrevCoord.x - PrevCoord00.x;
191- float y = PrevCoord.y - PrevCoord00.y;
192-
193- float Weight[4 ];
194- Weight[0 ] = (1.0 - x) * (1.0 - y);
195- Weight[1 ] = x * (1.0 - y);
196- Weight[2 ] = (1.0 - x) * y;
197- Weight[3 ] = x * y;
198-
199- float WeightSum = 0.0 ;
200- float WeightedCamZ = 0.0 ;
201- float4 WeightedColor = float4 (0.0 , 0.0 , 0.0 , 0.0 );
202- for (int SampleIdx = 0 ; SampleIdx < 4 ; ++SampleIdx)
207+ Desc.IsSuccess = BestTotalWeight > 0.1 ;
208+ if (Desc.IsSuccess)
203209 {
204- int2 Location = PrevCoord00i + int2 (SampleIdx & 0x01 , SampleIdx >> 1 );
205- float PrevCamZ = DepthToCameraZ (LoadPrevDepth (Location), g_PrevCamera.mProj);
206-
207- bool IsValidSample = ComputeDisocclusion (CurrCamZ, PrevCamZ) > (SSR_DISOCCLUSION_THRESHOLD / 2.0 );
208- Weight[SampleIdx] *= float (IsValidSample);
209-
210- WeightedColor += Weight[SampleIdx] * LoadPrevRadiance (Location);
211- WeightedCamZ += Weight[SampleIdx] * PrevCamZ;
212- WeightSum += Weight[SampleIdx];
210+ Desc.Color = (
211+ LoadPrevRadiance (BestFetchCoords.xy) * BestWeights.x +
212+ LoadPrevRadiance (BestFetchCoords.zy) * BestWeights.y +
213+ LoadPrevRadiance (BestFetchCoords.xw) * BestWeights.z +
214+ LoadPrevRadiance (BestFetchCoords.zw) * BestWeights.w
215+ ) / BestTotalWeight;
213216 }
214-
215- WeightSum = max (WeightSum, 1e-6 );
216- WeightedCamZ /= WeightSum;
217- WeightedColor /= WeightSum;
218-
219- Desc.IsSuccess = ComputeDisocclusion (CurrCamZ, WeightedCamZ) > SSR_DISOCCLUSION_THRESHOLD;
220- Desc.Color = WeightedColor;
221- }
217+ }
222218
223219 Desc.IsSuccess = Desc.IsSuccess && IsInsideScreen (Desc.PrevCoord, g_CurrCamera.f4ViewportSize.xy);
224220 return Desc;
0 commit comments