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.
 
 
 
 

150 lines
5.2 KiB

// This file is part of the FidelityFX SDK.
//
// Copyright (C) 2024 Advanced Micro Devices, Inc.
//
// 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.
#ifndef FFX_FRAMEINTERPOLATION_INPAINTING_H
#define FFX_FRAMEINTERPOLATION_INPAINTING_H
FfxFloat32x4 ComputeInpaintingLevel(FfxFloat32x2 fUv, const FfxInt32 iMipLevel, const FfxInt32x2 iTexSize)
{
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUv, iTexSize);
FfxFloat32x4 fColor = FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) {
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
if (IsOnScreen(iSamplePos, iTexSize)) {
FfxFloat32x4 fSample = LoadInpaintingPyramid(iMipLevel, iSamplePos);
const FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex] * FfxFloat32(fSample.w > 0.0f);
fColor += FfxFloat32x4(fSample.rgb * fWeight, fWeight);
}
}
return fColor;
}
FfxFloat32x3 ComputeInpainting(FfxInt32x2 iPxPos)
{
FfxFloat32x2 fUv = (iPxPos + 0.5f) / (DisplaySize());
FfxFloat32x4 fColor = FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
FfxFloat32 fWeightSum = 0.0f;
FfxInt32x2 iTexSize = DisplaySize();
for (FfxInt32 iMipLevel = 0; iMipLevel < 10; iMipLevel++) {
iTexSize /= 2;
FfxFloat32x4 fMipColor = ComputeInpaintingLevel(fUv, iMipLevel, iTexSize);
if (fMipColor.w > 0.0f) {
const FfxFloat32x3 fNormalizedMipColor = fMipColor.rgb / fMipColor.w;
const FfxFloat32 fMipWeight = ffxPow(1.0f - iMipLevel / 10.0f, 3.0f) * fMipColor.w;
fColor += FfxFloat32x4(fNormalizedMipColor, 1.0f) * fMipWeight;
}
}
return fColor.rgb / fColor.w;
}
void drawDebugTearLines(FfxInt32x2 iPxPos, inout FfxFloat32x3 fColor, inout FfxBoolean bWriteColor)
{
if (iPxPos.x < 16)
{
fColor.g = 1.f;
bWriteColor = true;
}
else if (iPxPos.x > DisplaySize().x - 16)
{
fColor += GetDebugBarColor();
bWriteColor = true;
}
}
void drawDebugResetIndicators(FfxInt32x2 iPxPos, inout FfxFloat32x3 fColor, inout FfxBoolean bWriteColor)
{
if (iPxPos.y < 32 && Reset())
{
fColor.r = 1.f;
bWriteColor = true;
}
else if (iPxPos.y > 32 && iPxPos.y < 64 && HasSceneChanged())
{
fColor.b = 1.f;
bWriteColor = true;
}
}
void computeInpainting(FfxInt32x2 iPxPos)
{
FfxBoolean bWriteColor = false;
FfxFloat32x4 fInterpolatedColor = RWLoadFrameinterpolationOutput(iPxPos);
const FfxFloat32 fInPaintingWeight = fInterpolatedColor.w;
if (fInPaintingWeight > FFX_FRAMEINTERPOLATION_EPSILON)
{
fInterpolatedColor.rgb = ffxLerp(fInterpolatedColor.rgb, ComputeInpainting(iPxPos) * FfxFloat32(DisplaySize().x > 0), fInPaintingWeight);
bWriteColor = true;
}
if (GetHUDLessAttachedFactor() == 1)
{
const FfxFloat32x3 fCurrentInterpolationSource = LoadCurrentBackbuffer(iPxPos).rgb;
const FfxFloat32x3 fPresentColor = LoadPresentBackbuffer(iPxPos).rgb;
if (any(FFX_GREATER_THAN(abs(fCurrentInterpolationSource - fPresentColor), FfxFloat32x3(0.0, 0.0, 0.0))))
{
const FfxFloat32 fStaticFactor = CalculateStaticContentFactor(RawRGBToLinear(fCurrentInterpolationSource), RawRGBToLinear(fPresentColor));
if (fStaticFactor > FFX_FRAMEINTERPOLATION_EPSILON)
{
fInterpolatedColor.rgb = ffxLerp(fInterpolatedColor.rgb, fPresentColor, fStaticFactor);
bWriteColor = true;
}
}
}
if ((GetDispatchFlags() & FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_TEAR_LINES) != 0)
{
drawDebugTearLines(iPxPos, fInterpolatedColor.rgb, bWriteColor);
}
if ((GetDispatchFlags() & FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_RESET_INDICATORS) != 0)
{
drawDebugResetIndicators(iPxPos, fInterpolatedColor.rgb, bWriteColor);
}
if (bWriteColor)
{
StoreFrameinterpolationOutput(iPxPos, FfxFloat32x4(fInterpolatedColor.rgb, 1.0f));
}
}
#endif // FFX_FRAMEINTERPOLATION_INPAINTING_H