You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
4.2 KiB
93 lines
4.2 KiB
// This file is part of the FidelityFX SDK.
|
|
//
|
|
// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
|
|
FFX_STATIC const FfxFloat32 DepthClipBaseScale = 4.0f;
|
|
|
|
FfxFloat32 ComputeSampleDepthClip(FFX_MIN16_I2 iPxSamplePos, FfxFloat32 fPreviousDepth, FfxFloat32 fPreviousDepthBilinearWeight, FfxFloat32 fCurrentDepthViewSpace)
|
|
{
|
|
FfxFloat32 fPrevNearestDepthViewSpace = abs(ConvertFromDeviceDepthToViewSpace(fPreviousDepth));
|
|
|
|
// Depth separation logic ref: See "Minimum Triangle Separation for Correct Z-Buffer Occlusion"
|
|
// Intention: worst case of formula in Figure4 combined with Ksep factor in Section 4
|
|
// TODO: check intention and improve, some banding visible
|
|
const FfxFloat32 fHalfViewportWidth = RenderSize().x * 0.5f;
|
|
FfxFloat32 fDepthThreshold = ffxMin(fCurrentDepthViewSpace, fPrevNearestDepthViewSpace);
|
|
|
|
// WARNING: Ksep only works with reversed-z with infinite projection.
|
|
const FfxFloat32 Ksep = 1.37e-05f;
|
|
FfxFloat32 fRequiredDepthSeparation = Ksep * fDepthThreshold * TanHalfFoV() * fHalfViewportWidth;
|
|
FfxFloat32 fDepthDiff = fCurrentDepthViewSpace - fPrevNearestDepthViewSpace;
|
|
|
|
FfxFloat32 fDepthClipFactor = (fDepthDiff > 0) ? ffxSaturate(fRequiredDepthSeparation / fDepthDiff) : 1.0f;
|
|
|
|
#ifdef _DEBUG
|
|
rw_debug_out[iPxSamplePos] = FfxFloat32x4(fCurrentDepthViewSpace, fPrevNearestDepthViewSpace, fDepthDiff, fDepthClipFactor);
|
|
#endif
|
|
|
|
return fPreviousDepthBilinearWeight * fDepthClipFactor * DepthClipBaseScale;
|
|
}
|
|
|
|
FfxFloat32 ComputeDepthClip(FfxFloat32x2 fUvSample, FfxFloat32 fCurrentDepthViewSpace)
|
|
{
|
|
FfxFloat32x2 fPxSample = fUvSample * RenderSize() - 0.5f;
|
|
FFX_MIN16_I2 iPxSample = FFX_MIN16_I2(floor(fPxSample));
|
|
FfxFloat32x2 fPxFrac = ffxFract(fPxSample);
|
|
|
|
const FfxFloat32 fBilinearWeights[2][2] = {
|
|
{
|
|
(1 - fPxFrac.x) * (1 - fPxFrac.y),
|
|
(fPxFrac.x) * (1 - fPxFrac.y)
|
|
},
|
|
{
|
|
(1 - fPxFrac.x) * (fPxFrac.y),
|
|
(fPxFrac.x) * (fPxFrac.y)
|
|
}
|
|
};
|
|
|
|
FfxFloat32 fDepth = 0.0f;
|
|
FfxFloat32 fWeightSum = 0.0f;
|
|
for (FfxInt32 y = 0; y <= 1; ++y) {
|
|
for (FfxInt32 x = 0; x <= 1; ++x) {
|
|
FFX_MIN16_I2 iSamplePos = iPxSample + FFX_MIN16_I2(x, y);
|
|
if (IsOnScreen(iSamplePos, FFX_MIN16_I2(RenderSize()))) {
|
|
FfxFloat32 fBilinearWeight = fBilinearWeights[y][x];
|
|
if (fBilinearWeight > reconstructedDepthBilinearWeightThreshold) {
|
|
fDepth += ComputeSampleDepthClip(iSamplePos, LoadReconstructedPrevDepth(iSamplePos), fBilinearWeight, fCurrentDepthViewSpace);
|
|
fWeightSum += fBilinearWeight;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (fWeightSum > 0) ? fDepth / fWeightSum : DepthClipBaseScale;
|
|
}
|
|
|
|
void DepthClip(FFX_MIN16_I2 iPxPos)
|
|
{
|
|
FfxFloat32x2 fDepthUv = (FfxFloat32x2(iPxPos) + 0.5f) / RenderSize();
|
|
FfxFloat32x2 fMotionVector = LoadDilatedMotionVector(iPxPos);
|
|
FfxFloat32x2 fDilatedUv = fDepthUv + fMotionVector;
|
|
FfxFloat32 fCurrentDepthViewSpace = abs(ConvertFromDeviceDepthToViewSpace(LoadDilatedDepth(iPxPos)));
|
|
|
|
FfxFloat32 fDepthClip = ComputeDepthClip(fDilatedUv, fCurrentDepthViewSpace);
|
|
|
|
StoreDepthClip(iPxPos, fDepthClip);
|
|
}
|