diff --git a/ffx-api/include/ffx_api/ffx_framegeneration.h b/ffx-api/include/ffx_api/ffx_framegeneration.h index 0ecdd4b4..1c526c81 100644 --- a/ffx-api/include/ffx_api/ffx_framegeneration.h +++ b/ffx-api/include/ffx_api/ffx_framegeneration.h @@ -85,6 +85,7 @@ struct ffxDispatchDescFrameGeneration void* commandList; ///< The command list on which to register render commands. struct FfxApiResource presentColor; ///< The current presentation color, this will be used as source data. struct FfxApiResource outputs[4]; ///< Destination targets (1 for each frame in numGeneratedFrames). + struct FfxApiResource distortionField; ///< The distortion field data. uint32_t numGeneratedFrames; ///< The number of frames to generate from the passed in color target. bool reset; ///< A boolean value which when set to true, indicates the camera has moved discontinuously. uint32_t backbufferTransferFunction; ///< The transfer function use to convert frame generation source color data to linear RGB. One of the values from FfxApiBackbufferTransferFunction. diff --git a/ffx-api/src/ffx_provider_framegeneration.cpp b/ffx-api/src/ffx_provider_framegeneration.cpp index a9413a5c..2001fa34 100644 --- a/ffx-api/src/ffx_provider_framegeneration.cpp +++ b/ffx-api/src/ffx_provider_framegeneration.cpp @@ -353,6 +353,7 @@ ffxReturnCode_t ffxProvider_FrameGeneration::Dispatch(ffxContext* context, const fiDispatchDesc.renderSize.width = prepDesc->renderSize.width; fiDispatchDesc.renderSize.height = prepDesc->renderSize.height; fiDispatchDesc.output = Convert(desc->outputs[0]); + fiDispatchDesc.distortionField = Convert(desc->distortionField); fiDispatchDesc.opticalFlowVector = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_VECTOR]); fiDispatchDesc.opticalFlowSceneChangeDetection = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_OUTPUT]); fiDispatchDesc.opticalFlowBlockSize = 8; diff --git a/framework/cauldron/framework/inc/shaders/tonemapping/builddistortionfield.hlsl b/framework/cauldron/framework/inc/shaders/tonemapping/builddistortionfield.hlsl new file mode 100644 index 00000000..5dfbd8c0 --- /dev/null +++ b/framework/cauldron/framework/inc/shaders/tonemapping/builddistortionfield.hlsl @@ -0,0 +1,56 @@ +// 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. + +#include "tonemappercommon.h" +#include "lensdistortion.h" + +//-------------------------------------------------------------------------------------- +// Texture definitions +//-------------------------------------------------------------------------------------- +RWTexture2D OutputTexture : register(u0); + +bool IsInsideLetterbox(int2 pixel) +{ + if (pixel.x > LetterboxRectBase.x && pixel.y > LetterboxRectBase.y && + pixel.x < LetterboxRectBase.x + LetterboxRectSize.x && + pixel.y <= LetterboxRectBase.y + LetterboxRectSize.y) + return true; + + return false; +} + +//-------------------------------------------------------------------------------------- +// Main function +//-------------------------------------------------------------------------------------- +[numthreads(NUM_THREAD_X, NUM_THREAD_Y, 1)] +void MainCS(uint3 dtID : SV_DispatchThreadID) +{ + const uint2 pixel = dtID.xy; + + float4 distortionField = float4(0.0f, 0.0f, 0.0f, 0.0f); + if (IsInsideLetterbox(pixel)) + { + float2 uv = (pixel + 0.5f) / LetterboxRectSize; + distortionField = GenerateDistortionField(uv); + } + OutputTexture[pixel] = distortionField; +} \ No newline at end of file diff --git a/framework/cauldron/framework/inc/shaders/tonemapping/lensdistortion.h b/framework/cauldron/framework/inc/shaders/tonemapping/lensdistortion.h new file mode 100644 index 00000000..cbdd558d --- /dev/null +++ b/framework/cauldron/framework/inc/shaders/tonemapping/lensdistortion.h @@ -0,0 +1,73 @@ +// 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 LENSDISTORTION_HLSL +#define LENSDISTORTION_HLSL + +#include "tonemappercommon.h" + +float2 BarrelDistortion(in float2 Uv) +{ + float2 remappedUv = (Uv * 2.0f) - 1.0f; + float r2 = remappedUv.x * remappedUv.x + remappedUv.y * remappedUv.y; + float2 outUv = remappedUv / (1.0f + LensDistortionStrength * r2); + return (outUv + 1.0f) / 2.0f; +} + +float2 InverseBarrelDistortion(in float2 Uv) +{ + float2 remappedUv = (Uv * 2.0f) - 1.0f; + float ru2 = remappedUv.x * remappedUv.x + remappedUv.y * remappedUv.y; + float num = sqrt(1.0f - 4.0f * LensDistortionStrength * ru2) - 1.0f; + float denom = 2.0f * LensDistortionStrength * sqrt(ru2); + float rd = -num / denom; + float2 outUV = remappedUv * (rd / sqrt(ru2)); + return (outUV + 1.0f) / 2.0f; +} + +float2 Zoom(in float2 Uv) +{ + float2 translatedCoord = (Uv - 0.5f) * 2.0f; + translatedCoord *= (1.0f - saturate(LensDistortionZoom)); + return (translatedCoord + 1.0f) / 2.0f; +} + +float2 InverseZoom(in float2 Uv) +{ + float2 translatedCoord = (Uv - 0.5f) * 2.0f; + translatedCoord /= (1.0f - saturate(LensDistortionZoom)); + return (translatedCoord + 1.0f) / 2.0f; +} + +float4 GenerateDistortionField(in float2 Uv) +{ + float2 xy = Zoom(BarrelDistortion(Uv)) - Uv; + float2 zw = InverseBarrelDistortion(InverseZoom(Uv)) - Uv; + return float4(xy, zw); +} + +float2 ApplyLensDistortion(in float2 Uv) +{ + return Zoom(BarrelDistortion(Uv)); +} + +#endif \ No newline at end of file diff --git a/framework/cauldron/framework/inc/shaders/tonemapping/tonemappercommon.h b/framework/cauldron/framework/inc/shaders/tonemapping/tonemappercommon.h index a5b62184..cdea19ee 100644 --- a/framework/cauldron/framework/inc/shaders/tonemapping/tonemappercommon.h +++ b/framework/cauldron/framework/inc/shaders/tonemapping/tonemappercommon.h @@ -20,6 +20,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#ifndef TONEMAPPERCOMMON_H +#define TONEMAPPERCOMMON_H + #if __cplusplus #pragma once #include @@ -42,10 +45,17 @@ struct TonemapperCBData mutable uint32_t ToneMapper = 0; float DisplayMaxLuminance; DisplayMode MonitorDisplayMode; + Mat4 ContentToMonitorRecMatrix; + int32_t LetterboxRectBase[2]; int32_t LetterboxRectSize[2]; + uint32_t UseAutoExposure = 0; + uint32_t LensDistortionEnabled = 0; + float LensDistortionStrength = -0.2f; + float LensDistortionZoom = 0.4f; + }; #else @@ -67,5 +77,10 @@ cbuffer TonemapperCBData : register(b0) int2 LetterboxRectBase : packoffset(c5.x); int2 LetterboxRectSize : packoffset(c5.z); bool UseAutoExposure : packoffset(c6.x); + bool LensDistortionEnabled : packoffset(c6.y); + float LensDistortionStrength : packoffset(c6.z); + float LensDistortionZoom : packoffset(c6.w); } #endif // __cplusplus + +#endif // TONEMAPPERCOMMON_H diff --git a/framework/cauldron/framework/inc/shaders/tonemapping/tonemapping.hlsl b/framework/cauldron/framework/inc/shaders/tonemapping/tonemapping.hlsl index 9448b5f4..8e64e39d 100644 --- a/framework/cauldron/framework/inc/shaders/tonemapping/tonemapping.hlsl +++ b/framework/cauldron/framework/inc/shaders/tonemapping/tonemapping.hlsl @@ -23,6 +23,7 @@ #include "tonemappers.hlsl" #include "tonemappercommon.h" #include "transferfunction.h" +#include "lensdistortion.h" //-------------------------------------------------------------------------------------- // Texture definitions @@ -48,7 +49,14 @@ void MainCS(uint3 dtID : SV_DispatchThreadID) } else { - const int2 coordInLetterbox = dtID.xy - LetterboxRectBase; + int2 coordInLetterbox = dtID.xy - LetterboxRectBase; + + if (LensDistortionEnabled) + { + const float2 uvInLetterbox = (coordInLetterbox + 0.5f) / LetterboxRectSize; + const float2 distortedUvInLetterbox = ApplyLensDistortion(uvInLetterbox); + coordInLetterbox = distortedUvInLetterbox * LetterboxRectSize; + } const float4 texColor = InputTexture[coordInLetterbox]; const float2 autoExposure = AutomaticExposureValue[int2(0, 0)]; diff --git a/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.cpp b/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.cpp index 0ff7bcb8..7288de05 100644 --- a/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.cpp +++ b/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.cpp @@ -65,6 +65,8 @@ void ToneMappingRenderModule::Init(const json& InitData) m_pRenderTargetOut = GetFramework()->GetRenderTexture(L"SwapChainProxy"); CauldronAssert(ASSERT_CRITICAL, m_pRenderTargetOut != nullptr, L"Couldn't find the render target for the tone mapper output"); + m_pDistortionField = GetFramework()->GetRenderTexture(L"DistortionField"); + TextureDesc desc = TextureDesc::Tex2D(L"AutomaticExposureSpdAtomicCounter", ResourceFormat::R32_UINT, 1, 1, 1, 1, ResourceFlags::AllowUnorderedAccess); m_pAutomaticExposureSpdAtomicCounter = GetDynamicResourcePool()->CreateRenderTexture(&desc); @@ -133,6 +135,31 @@ void ToneMappingRenderModule::Init(const json& InitData) m_pAutoExposureSpdParameters->SetTextureUAV(m_pAutomaticExposureMips5, ViewDimension::Texture2D, 2); m_pAutoExposureSpdParameters->SetTextureUAV(m_pAutomaticExposureValue, ViewDimension::Texture2D, 3); + { + // Init build distortion field pipeline + RootSignatureDesc buildDistortionFieldSignatureDesc; + buildDistortionFieldSignatureDesc.AddConstantBufferView(0, ShaderBindStage::Compute, 1); + buildDistortionFieldSignatureDesc.AddTextureUAVSet(0, ShaderBindStage::Compute, 1); + m_pBuildDistortionFieldRootSignature = RootSignature::CreateRootSignature(L"BuildDistortionFieldRenderPass_RootSignature", buildDistortionFieldSignatureDesc); + + // Setup the pipeline object + PipelineDesc buildDistortionFieldPsoDesc; + buildDistortionFieldPsoDesc.SetRootSignature(m_pBuildDistortionFieldRootSignature); + + // Setup the shaders to build on the pipeline object + shaderPath = L"builddistortionfield.hlsl"; + + DefineList buildDistortionFieldDefineList; + buildDistortionFieldDefineList.insert(std::make_pair(L"NUM_THREAD_X", std::to_wstring(g_NumThreadX))); + buildDistortionFieldDefineList.insert(std::make_pair(L"NUM_THREAD_Y", std::to_wstring(g_NumThreadY))); + buildDistortionFieldPsoDesc.AddShaderDesc(ShaderBuildDesc::Compute(shaderPath.c_str(), L"MainCS", ShaderModel::SM6_0, &buildDistortionFieldDefineList)); + + m_pBuildDistortionFieldPipelineObj = PipelineObject::CreatePipelineObject(L"BuildDistortionFieldRenderPass_PipelineObj", buildDistortionFieldPsoDesc); + + m_pBuildDistortionFieldParameters = ParameterSet::CreateParameterSet(m_pBuildDistortionFieldRootSignature); + m_pBuildDistortionFieldParameters->SetRootConstantBufferResource(GetDynamicBufferPool()->GetResource(), sizeof(TonemapperCBData), 0); + m_pBuildDistortionFieldParameters->SetTextureUAV(m_pDistortionField, ViewDimension::Texture2D, 0); + } // Init tonemapper // root signature RootSignatureDesc tonemapperSignatureDesc; @@ -182,6 +209,10 @@ void ToneMappingRenderModule::Init(const json& InitData) } ); uiSection->RegisterUIElement("AutoExposure", (bool&)m_TonemapperConstantData.UseAutoExposure); + + uiSection->RegisterUIElement("Lens Distortion Enable", (bool&)m_TonemapperConstantData.LensDistortionEnabled); + uiSection->RegisterUIElement>("Lens Distortion Strength", m_TonemapperConstantData.LensDistortionStrength, -1.f, 1.f, m_TonemapperConstantData.LensDistortionEnabled, nullptr, true); + uiSection->RegisterUIElement>("Lens Distortion Zoom", m_TonemapperConstantData.LensDistortionZoom, 0.f, 1.f, m_TonemapperConstantData.LensDistortionEnabled, nullptr, true); } // We are now ready for use @@ -194,6 +225,10 @@ ToneMappingRenderModule::~ToneMappingRenderModule() delete m_pAutoExposureSpdPipelineObj; delete m_pAutoExposureSpdParameters; + delete m_pBuildDistortionFieldRootSignature; + delete m_pBuildDistortionFieldPipelineObj; + delete m_pBuildDistortionFieldParameters; + delete m_pTonemapperRootSignature; delete m_pTonemapperPipelineObj; delete m_pTonemapperParameters; @@ -238,7 +273,7 @@ void ToneMappingRenderModule::Execute(double deltaTime, CommandList* pCmdList) Dispatch(pCmdList, m_DispatchThreadGroupCountXY[0], m_DispatchThreadGroupCountXY[1], 1); } - + { GPUScopedProfileCapture tonemappingMarker(pCmdList, L"ToneMapping"); @@ -302,4 +337,33 @@ void ToneMappingRenderModule::Execute(double deltaTime, CommandList* pCmdList) ResourceState::NonPixelShaderResource | ResourceState::PixelShaderResource); ResourceBarrier(pCmdList, 1, &barrier); } + + if (m_TonemapperConstantData.LensDistortionEnabled) + { + GPUScopedProfileCapture distortionFieldMarker(pCmdList, L"Build Distortion Field"); + + Barrier barrierToWrite = Barrier::Transition(m_pDistortionField->GetResource(), + ResourceState::NonPixelShaderResource | ResourceState::PixelShaderResource, + ResourceState::UnorderedAccess); + ResourceBarrier(pCmdList, 1, &barrierToWrite); + + // Allocate a dynamic constant buffer and set + BufferAddressInfo bufferInfo = GetDynamicBufferPool()->AllocConstantBuffer(sizeof(TonemapperCBData), &m_TonemapperConstantData); + m_pBuildDistortionFieldParameters->UpdateRootConstantBuffer(&bufferInfo, 0); + + // bind all the parameters + m_pBuildDistortionFieldParameters->Bind(pCmdList, m_pBuildDistortionFieldPipelineObj); + + // Set pipeline and dispatch + SetPipelineState(pCmdList, m_pBuildDistortionFieldPipelineObj); + + const uint32_t numGroupX = DivideRoundingUp(m_pDistortionField->GetDesc().Width, g_NumThreadX); + const uint32_t numGroupY = DivideRoundingUp(m_pDistortionField->GetDesc().Height, g_NumThreadY); + Dispatch(pCmdList, numGroupX, numGroupY, 1); + + Barrier barrierToRead = Barrier::Transition(m_pDistortionField->GetResource(), + ResourceState::UnorderedAccess, + ResourceState::NonPixelShaderResource | ResourceState::PixelShaderResource); + ResourceBarrier(pCmdList, 1, &barrierToRead); + } } diff --git a/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.h b/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.h index a203b30b..7c147e7a 100644 --- a/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.h +++ b/framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.h @@ -57,14 +57,18 @@ class ToneMappingRenderModule : public cauldron::RenderModule // Constant data uint32_t m_DispatchThreadGroupCountXY[2]; - AutoExposureSpdConstants m_AutoExposureSpdConstants; - TonemapperCBData m_TonemapperConstantData; + AutoExposureSpdConstants m_AutoExposureSpdConstants; + TonemapperCBData m_TonemapperConstantData; // common cauldron::RootSignature* m_pAutoExposureSpdRootSignature = nullptr; cauldron::PipelineObject* m_pAutoExposureSpdPipelineObj = nullptr; cauldron::ParameterSet* m_pAutoExposureSpdParameters = nullptr; + cauldron::RootSignature* m_pBuildDistortionFieldRootSignature = nullptr; + cauldron::PipelineObject* m_pBuildDistortionFieldPipelineObj = nullptr; + cauldron::ParameterSet* m_pBuildDistortionFieldParameters = nullptr; + cauldron::RootSignature* m_pTonemapperRootSignature = nullptr; const cauldron::RasterView* m_pRasterView = nullptr; cauldron::PipelineObject* m_pTonemapperPipelineObj = nullptr; @@ -77,5 +81,6 @@ class ToneMappingRenderModule : public cauldron::RenderModule cauldron::SamplerDesc m_LinearSamplerDesc; const cauldron::Texture* m_pRenderTargetIn = nullptr; - const cauldron::Texture* m_pRenderTargetOut = nullptr; + const cauldron::Texture* m_pRenderTargetOut = nullptr; + const cauldron::Texture* m_pDistortionField = nullptr; }; diff --git a/samples/fsrapi/config/fsrapiconfig.json b/samples/fsrapi/config/fsrapiconfig.json index e465b4d0..d61a2d57 100644 --- a/samples/fsrapi/config/fsrapiconfig.json +++ b/samples/fsrapi/config/fsrapiconfig.json @@ -3,6 +3,11 @@ "MotionVectorGeneration": "GBufferRenderModule", "RenderResources": { + "DistortionField": { + "Format": "RGBA16_FLOAT", + "AllowUAV": true, + "RenderResolution": false + }, "ReactiveMask": { "Format": "R8_UNORM", "AllowUAV": true, diff --git a/samples/fsrapi/fsrapirendermodule.cpp b/samples/fsrapi/fsrapirendermodule.cpp index 4e985d1d..76a638e5 100644 --- a/samples/fsrapi/fsrapirendermodule.cpp +++ b/samples/fsrapi/fsrapirendermodule.cpp @@ -68,9 +68,10 @@ void FSRRenderModule::Init(const json& initData) m_pTonemappedColorTarget = GetFramework()->GetRenderTexture(L"SwapChainProxy"); m_pDepthTarget = GetFramework()->GetRenderTexture(L"DepthTarget"); m_pMotionVectors = GetFramework()->GetRenderTexture(L"GBufferMotionVectorRT"); + m_pDistortionField = GetFramework()->GetRenderTexture(L"DistortionField"); m_pReactiveMask = GetFramework()->GetRenderTexture(L"ReactiveMask"); m_pCompositionMask = GetFramework()->GetRenderTexture(L"TransCompMask"); - CauldronAssert(ASSERT_CRITICAL, m_pMotionVectors && m_pReactiveMask && m_pCompositionMask, L"Could not get one of the needed resources for FSR Rendermodule."); + CauldronAssert(ASSERT_CRITICAL, m_pMotionVectors && m_pDistortionField && m_pReactiveMask && m_pCompositionMask, L"Could not get one of the needed resources for FSR Rendermodule."); // Get a CPU resource view that we'll use to map the render target to GetResourceViewAllocator()->AllocateCPURenderViews(&m_pRTResourceView); @@ -438,6 +439,9 @@ void FSRRenderModule::InitUI(UISection* pUISection) // Use mask m_UIElements.emplace_back(pUISection->RegisterUIElement("Use Transparency and Composition Mask", m_UseMask, m_EnableMaskOptions, nullptr, false)); + // Use distortion field + m_UIElements.emplace_back(pUISection->RegisterUIElement("Use Distortion Field Input", m_UseDistortionField, nullptr, false)); + // Sharpening m_UIElements.emplace_back(pUISection->RegisterUIElement("RCAS Sharpening", m_RCASSharpen, nullptr, false, false)); m_UIElements.emplace_back(pUISection->RegisterUIElement>("Sharpness", m_Sharpness, 0.f, 1.f, m_RCASSharpen, nullptr, false)); @@ -990,6 +994,7 @@ void FSRRenderModule::Execute(double deltaTime, CommandList* pCmdList) #endif // defined(FFX_API_DX12) dispatchFgPrep.depth = SDKWrapper::ffxGetResourceApi(m_pDepthTarget->GetResource(), FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); dispatchFgPrep.motionVectors = SDKWrapper::ffxGetResourceApi(m_pMotionVectors->GetResource(), FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + dispatchFgPrep.flags = 0; dispatchFgPrep.jitterOffset.x = -m_JitterX; @@ -1094,6 +1099,11 @@ void FSRRenderModule::Execute(double deltaTime, CommandList* pCmdList) dispatchFg.generationRect.width = resInfo.UpscaleWidth; dispatchFg.generationRect.height = resInfo.UpscaleHeight; + if (m_UseDistortionField) + dispatchFg.distortionField = SDKWrapper::ffxGetResourceApi(m_pDistortionField->GetResource(), FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + else + dispatchFg.distortionField = SDKWrapper::ffxGetResourceApi(nullptr, FFX_API_RESOURCE_STATE_PIXEL_COMPUTE_READ); + #if defined(FFX_API_DX12) ffx::QueryDescFrameGenerationSwapChainInterpolationCommandListDX12 queryCmdList{}; queryCmdList.pOutCommandList = &dispatchFg.commandList; diff --git a/samples/fsrapi/fsrapirendermodule.h b/samples/fsrapi/fsrapirendermodule.h index 0fe25d51..7ad636f1 100644 --- a/samples/fsrapi/fsrapirendermodule.h +++ b/samples/fsrapi/fsrapirendermodule.h @@ -161,6 +161,7 @@ class FSRRenderModule : public cauldron::RenderModule bool m_IsNonNative = true; bool m_UpscaleRatioEnabled = false; bool m_UseMask = true; + bool m_UseDistortionField = false; bool m_RCASSharpen = true; bool m_SharpnessEnabled = false; bool m_NeedReInit = false; @@ -201,6 +202,7 @@ class FSRRenderModule : public cauldron::RenderModule const cauldron::Texture* m_pTempTexture = nullptr; const cauldron::Texture* m_pDepthTarget = nullptr; const cauldron::Texture* m_pMotionVectors = nullptr; + const cauldron::Texture* m_pDistortionField = nullptr; const cauldron::Texture* m_pReactiveMask = nullptr; const cauldron::Texture* m_pCompositionMask = nullptr; const cauldron::Texture* m_pOpaqueTexture = nullptr; diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_glsl.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_glsl.h index b7d41919..f49d63da 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_glsl.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_glsl.h @@ -47,7 +47,7 @@ FfxFloat32 deltaTime; FfxInt32 HUDLessAttachedFactor; - FfxFloat32x2 UNUSED; + FfxInt32x2 distortionFieldSize; FfxFloat32x2 opticalFlowScale; FfxInt32 opticalFlowBlockSize; @@ -138,6 +138,11 @@ return cbFI.HUDLessAttachedFactor; } + FfxInt32x2 GetDistortionFieldSize() + { + return distortionFieldSize; + } + FfxUInt32 GetDispatchFlags() { return cbFI.dispatchFlags; @@ -465,6 +470,14 @@ layout (set = 0, binding = 1000) uniform sampler s_LinearClamp; } #endif +#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD) + layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD) uniform texture2D r_input_distortion_field; + FfxFloat32x4 SampleDistortionField(FFX_PARAMETER_IN FfxFloat32x2 fUv) + { + return textureLod(sampler2D(r_input_distortion_field, s_LinearClamp), fUv, 0.0); + } +#endif + /////////////////////////////////////////////// // declare UAVs and UAV accessors /////////////////////////////////////////////// diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_hlsl.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_hlsl.h index 470708c1..1bcf1ecb 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_hlsl.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_callbacks_hlsl.h @@ -59,7 +59,7 @@ FfxFloat32 deltaTime; FfxInt32 HUDLessAttachedFactor; - FfxFloat32x2 UNUSED; + FfxInt32x2 distortionFieldSize; FfxFloat32x2 opticalFlowScale; FfxInt32 opticalFlowBlockSize; @@ -150,6 +150,11 @@ return HUDLessAttachedFactor; } + FfxInt32x2 GetDistortionFieldSize() + { + return distortionFieldSize; + } + FfxUInt32 GetDispatchFlags() { return dispatchFlags; @@ -497,6 +502,15 @@ FfxFloat32x2 LoadInputMotionVector(FfxInt32x2 iPxDilatedMotionVectorPos) return fUvMotionVector; } #endif + +#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD) + Texture2D r_input_distortion_field : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD); + FfxFloat32x4 SampleDistortionField(FFX_PARAMETER_IN FfxFloat32x2 fUv) + { + return r_input_distortion_field.SampleLevel(s_LinearClamp, fUv, 0); + } +#endif + /////////////////////////////////////////////// // declare UAVs and UAV accessors /////////////////////////////////////////////// diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_debug_view.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_debug_view.h index d94defec..18506e3d 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_debug_view.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_debug_view.h @@ -100,10 +100,21 @@ void drawDisocclusionMask(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport StoreFrameinterpolationOutput(iPxPos, FfxFloat32x4(fDisocclusionFactor, 0, 1)); } -void drawPresentBackbuffer(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp) +void drawDistortionField() { FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); + FfxFloat32x2 fDistortionField = abs(SampleDistortionField(fUv).xy); + + FfxFloat32x4 fPresentColor = FfxFloat32x4(fDistortionField * 10.0f, 0.0f, 1.0f); + + StoreFrameinterpolationOutput(iPxPos, fPresentColor); +} + +void drawPresentBackbuffer(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp) +{ + FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); + FfxFloat32x4 fPresentColor = getUnusedIndicationColor(iPxPos, vp); if (GetHUDLessAttachedFactor() == 1) diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_disocclusion_mask.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_disocclusion_mask.h index d9a9e29d..32e09246 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_disocclusion_mask.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_disocclusion_mask.h @@ -46,13 +46,17 @@ FfxFloat32 ComputeSampleDepthClip(FfxInt32x2 iPxSamplePos, FfxFloat32 fPreviousD FfxFloat32 LoadEstimatedDepth(FfxUInt32 estimatedIndex, FfxInt32x2 iSamplePos) { + const FfxFloat32x2 fUv = FfxFloat32x2(iSamplePos + 0.5f) / RenderSize(); + const FfxFloat32x4 fDistortionField = SampleDistortionField(fUv); + FfxInt32x2 iDistortionPixelOffset = fDistortionField.xy * RenderSize(); + if (estimatedIndex == 0) { - return LoadReconstructedDepthPreviousFrame(iSamplePos); + return LoadReconstructedDepthPreviousFrame(iSamplePos + iDistortionPixelOffset); } else if (estimatedIndex == 1) { - return LoadDilatedDepth(iSamplePos); + return LoadDilatedDepth(iSamplePos + iDistortionPixelOffset); } return 0; diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h index bc909961..4a88fcee 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h @@ -35,12 +35,16 @@ FfxUInt32 getPriorityFactorFromViewSpaceDepth(FfxFloat32 fViewSpaceDepthInMeters void computeGameFieldMvs(FfxInt32x2 iPxPos) { const FfxFloat32x2 fUvInScreenSpace = (FfxFloat32x2(iPxPos) + 0.5f) / RenderSize(); + + const FfxFloat32x4 fDistortionField = SampleDistortionField(fUvInScreenSpace); + const FfxInt32x2 iDistortionPixelOffset = fDistortionField.xy * RenderSize(); + const FfxFloat32x2 fUvInInterpolationRectStart = FfxFloat32x2(InterpolationRectBase()) / DisplaySize(); const FfxFloat32x2 fUvLetterBoxScale = FfxFloat32x2(InterpolationRectSize()) / DisplaySize(); const FfxFloat32x2 fUvInInterpolationRect = fUvInInterpolationRectStart + fUvInScreenSpace * fUvLetterBoxScale; - const FfxFloat32 fDepthSample = LoadDilatedDepth(iPxPos); - const FfxFloat32x2 fGameMotionVector = LoadDilatedMotionVector(iPxPos); + const FfxFloat32 fDepthSample = LoadDilatedDepth(iPxPos + iDistortionPixelOffset); + const FfxFloat32x2 fGameMotionVector = LoadDilatedMotionVector(iPxPos + iDistortionPixelOffset); const FfxFloat32x2 fMotionVectorHalf = fGameMotionVector * 0.5f; const FfxFloat32x2 fInterpolatedLocationUv = fUvInScreenSpace + fMotionVectorHalf; @@ -48,7 +52,7 @@ void computeGameFieldMvs(FfxInt32x2 iPxPos) const FfxUInt32 uHighPriorityFactorPrimary = getPriorityFactorFromViewSpaceDepth(fViewSpaceDepth); FfxFloat32x3 prevBackbufferCol = SamplePreviousBackbuffer(fUvInInterpolationRect).xyz; - FfxFloat32x3 curBackbufferCol = SamplePreviousBackbuffer(fUvInInterpolationRect + fGameMotionVector * fUvLetterBoxScale).xyz; + FfxFloat32x3 curBackbufferCol = SampleCurrentBackbuffer(fUvInInterpolationRect + fGameMotionVector * fUvLetterBoxScale).xyz; FfxFloat32 prevLuma = 0.001f + RawRGBToLuminance(prevBackbufferCol); FfxFloat32 currLuma = 0.001f + RawRGBToLuminance(curBackbufferCol); diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field.h index 23790741..301dfc5e 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field.h @@ -30,7 +30,10 @@ void computeOpticalFlowFieldMvs(FfxUInt32x2 dtID, FfxFloat32x2 fOpticalFlowVecto const FfxFloat32 scaleFactor = 1.0f; FfxFloat32x2 fMotionVectorHalf = fOpticalFlowVector * 0.5f; - FfxFloat32 fDilatedDepth = ConvertFromDeviceDepthToViewSpace(LoadDilatedDepth(FfxInt32x2(dtID))); + const FfxFloat32x4 fDistortionField = SampleDistortionField(fUv); + const FfxInt32x2 iDistortionPixelOffset = fDistortionField.xy * RenderSize(); + + FfxFloat32 fDilatedDepth = ConvertFromDeviceDepthToViewSpace(LoadDilatedDepth(FfxInt32x2(dtID + iDistortionPixelOffset))); FfxFloat32x3 prevBackbufferCol = SamplePreviousBackbuffer(fUv).xyz; FfxFloat32x3 curBackbufferCol = SampleCurrentBackbuffer(fUv + fOpticalFlowVector).xyz; diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth.h index 3f6cdbc4..ac9215d2 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth.h @@ -50,8 +50,12 @@ void ReconstructPrevDepth(FfxInt32x2 iPxPos, FfxUInt32 depthTarget, FfxFloat32 f void reconstructPreviousDepth(FfxInt32x2 iPxPos) { - FfxFloat32x2 fMotionVector = LoadDilatedMotionVector(iPxPos); - FfxFloat32 fDilatedDepth = LoadDilatedDepth(iPxPos); + const FfxFloat32x2 fUv = (iPxPos + FfxFloat32(0.5f)) / RenderSize(); + const FfxFloat32x4 fDistortionField = SampleDistortionField(fUv); + const FfxInt32x2 iDistortionPixelOffset = fDistortionField.xy * RenderSize(); + + FfxFloat32x2 fMotionVector = LoadDilatedMotionVector(iPxPos + iDistortionPixelOffset); + FfxFloat32 fDilatedDepth = LoadDilatedDepth(iPxPos + iDistortionPixelOffset); ReconstructPrevDepth(iPxPos, 1, fDilatedDepth, fMotionVector * 0.5f, RenderSize()); } diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_resources.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_resources.h index 3bc5a94e..b6be8a2f 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_resources.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_resources.h @@ -88,7 +88,10 @@ #define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME_0 50 #define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME_1 51 // code relies on them being interleaved -#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNT 52 +#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEFAULT_DISTORTION_FIELD 52 +#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DISTORTION_FIELD 53 + +#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNT 54 #define FFX_FRAMEINTERPOLATION_CONSTANTBUFFER_IDENTIFIER 0 #define FFX_FRAMEINTERPOLATION_INPAINTING_PYRAMID_CONSTANTBUFFER_IDENTIFIER 1 diff --git a/sdk/include/FidelityFX/host/ffx_frameinterpolation.h b/sdk/include/FidelityFX/host/ffx_frameinterpolation.h index 1a2b2f2e..89026e44 100644 --- a/sdk/include/FidelityFX/host/ffx_frameinterpolation.h +++ b/sdk/include/FidelityFX/host/ffx_frameinterpolation.h @@ -223,6 +223,7 @@ typedef struct FfxFrameInterpolationDispatchDescription { FfxDimensions2D renderSize; ///< The dimensions used to render game content, dilatedDepth, dilatedMotionVectors are expected to be of ths size. FfxResource currentBackBuffer; ///< The current presentation color, if currentBackBuffer_HUDLess is not used, this will be used as interpolation source data. FfxResource currentBackBuffer_HUDLess; ///< The current presentation color without HUD content, when use it will be used as interpolation source data. + FfxResource distortionField; ///< The distortion field data. FfxResource output; ///< The output resource where to store the interpolated result. FfxRect2D interpolationRect; ///< The area of the backbuffer that should be used for interpolation in case only a part of the screen is used e.g. due to movie bars diff --git a/sdk/include/FidelityFX/host/ffx_fsr3.h b/sdk/include/FidelityFX/host/ffx_fsr3.h index fc7e7275..f3dde283 100644 --- a/sdk/include/FidelityFX/host/ffx_fsr3.h +++ b/sdk/include/FidelityFX/host/ffx_fsr3.h @@ -197,6 +197,7 @@ typedef struct FfxFsr3DispatchFrameGenerationPrepareDescription FfxCommandList commandList; ///< The FfxCommandList to record FSR2 rendering commands into. FfxResource depth; ///< A FfxResource containing 32bit depth values for the current frame (at render resolution). FfxResource motionVectors; ///< A FfxResource containing 2-dimensional motion vectors (at render resolution if FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS is not set). + FfxResource distortionField; ///< A FfxResource containing 2-dimensional uv offsets describing the amount of distortion applied to the final image. FfxFloatCoords2D jitterOffset; ///< The subpixel jitter offset applied to the camera. FfxFloatCoords2D motionVectorScale; ///< The scale factor to apply to motion vectors. FfxDimensions2D renderSize; ///< The resolution that was used for rendering the input resources. diff --git a/sdk/include/FidelityFX/host/ffx_types.h b/sdk/include/FidelityFX/host/ffx_types.h index 4ac867e9..655f5252 100644 --- a/sdk/include/FidelityFX/host/ffx_types.h +++ b/sdk/include/FidelityFX/host/ffx_types.h @@ -1246,6 +1246,7 @@ typedef struct FfxPresentCallbackDescription typedef struct FfxFrameGenerationDispatchDescription { FfxCommandList commandList; ///< The command list on which to register render commands FfxResource presentColor; ///< The current presentation color, this will be used as interpolation source data. + FfxResource distortionField; ///< A resource containing distortion offset data used when distortion post effects are enabled. FfxResource outputs[4]; ///< Interpolation destination targets (1 for each frame in numInterpolatedFrames) uint32_t numInterpolatedFrames; ///< The number of frames to interpolate from the passed in color target bool reset; ///< A boolean value which when set to true, indicates the camera has moved discontinuously. diff --git a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.hlsl b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.hlsl index e8447289..46af50b7 100644 --- a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.hlsl +++ b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.hlsl @@ -28,6 +28,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_PRESENT_BACKBUFFER 5 #define FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID 6 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 7 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 8 #define FFX_FRAMEINTERPOLATION_BIND_UAV_OUTPUT 0 diff --git a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.hlsl b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.hlsl index b26f4320..196dd4eb 100644 --- a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.hlsl +++ b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.hlsl @@ -26,6 +26,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 3 #define FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME 4 #define FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID 5 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 6 #define FFX_FRAMEINTERPOLATION_BIND_UAV_DISOCCLUSION_MASK 0 diff --git a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.hlsl b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.hlsl index 20f87b5f..79857f34 100644 --- a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.hlsl +++ b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.hlsl @@ -24,6 +24,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 1 #define FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE 2 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 3 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 4 #define FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_X 0 #define FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_Y 1 diff --git a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.hlsl b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.hlsl index f9e204c0..ce100dcf 100644 --- a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.hlsl +++ b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.hlsl @@ -25,6 +25,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 2 #define FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE 3 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 4 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 5 #define FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X 0 #define FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y 1 diff --git a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.hlsl b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.hlsl index 3aed49dd..5ae0dff4 100644 --- a/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.hlsl +++ b/sdk/src/backends/dx12/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.hlsl @@ -23,6 +23,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_MOTION_VECTORS 0 #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 1 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 2 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 3 #define FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME 0 diff --git a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.glsl b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.glsl index 030dadad..16ba153c 100644 --- a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.glsl +++ b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_debug_view_pass.glsl @@ -35,6 +35,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_PRESENT_BACKBUFFER 5 #define FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID 6 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 7 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 8 #define FFX_FRAMEINTERPOLATION_BIND_UAV_OUTPUT 8 diff --git a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.glsl b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.glsl index 0e3a254a..3bb3ca58 100644 --- a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.glsl +++ b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_disocclusion_mask_pass.glsl @@ -31,6 +31,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 3 #define FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME 4 #define FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID 5 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 6 #define FFX_FRAMEINTERPOLATION_BIND_UAV_DISOCCLUSION_MASK 6 diff --git a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.glsl b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.glsl index 0c0d244d..084edb8f 100644 --- a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.glsl +++ b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field_pass.glsl @@ -29,6 +29,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 1 #define FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE 2 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 3 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 4 #define FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_X 4 #define FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_Y 5 diff --git a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.glsl b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.glsl index e2357379..d65ce16e 100644 --- a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.glsl +++ b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_optical_flow_vector_field_pass.glsl @@ -30,6 +30,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 2 #define FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE 3 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 4 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 5 #define FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X 5 #define FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y 6 diff --git a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.glsl b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.glsl index c1200129..2c50a4a2 100644 --- a/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.glsl +++ b/sdk/src/backends/vk/shaders/frameinterpolation/ffx_frameinterpolation_reconstruct_previous_depth_pass.glsl @@ -28,6 +28,7 @@ #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_MOTION_VECTORS 0 #define FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH 1 #define FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE 2 +#define FFX_FRAMEINTERPOLATION_BIND_SRV_DISTORTION_FIELD 3 #define FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME 3 diff --git a/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp b/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp index 982905a0..2ed1e1e2 100644 --- a/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp +++ b/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp @@ -46,6 +46,7 @@ static const ResourceBinding srvResourceBindingTable[] = // Frame Interpolation textures {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEPTH, L"r_input_depth"}, {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_MOTION_VECTORS, L"r_input_motion_vectors"}, + {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DISTORTION_FIELD, L"r_input_distortion_field"}, {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_DEPTH, L"r_dilated_depth"}, {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS, L"r_dilated_motion_vectors"}, @@ -376,6 +377,7 @@ static FfxErrorCode frameinterpolationCreate(FfxFrameInterpolationContext_Privat } uint8_t defaultReactiveMaskData = 0U; + uint8_t defaultDistortionFieldData[4] = { 0, 0, 0, 0 }; uint32_t atomicInitData[2] = { 0, 0 }; float defaultExposure[] = { 0.0f, 0.0f }; const FfxResourceType texture1dResourceType = (context->contextDescription.flags & FFX_FRAMEINTERPOLATION_ENABLE_TEXTURE1D_USAGE) ? FFX_RESOURCE_TYPE_TEXTURE1D : FFX_RESOURCE_TYPE_TEXTURE2D; @@ -414,6 +416,9 @@ static FfxErrorCode frameinterpolationCreate(FfxFrameInterpolationContext_Privat FFX_SURFACE_FORMAT_R32_UINT, contextDescription->maxRenderSize.width, contextDescription->maxRenderSize.height, 1, FFX_RESOURCE_FLAGS_NONE, {FFX_RESOURCE_INIT_DATA_TYPE_UNINITIALIZED}}, {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME_1, L"FI_ReconstructedDepth_1", FFX_RESOURCE_TYPE_TEXTURE2D, FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, contextDescription->maxRenderSize.width, contextDescription->maxRenderSize.height, 1, FFX_RESOURCE_FLAGS_NONE, {FFX_RESOURCE_INIT_DATA_TYPE_UNINITIALIZED}}, + + {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEFAULT_DISTORTION_FIELD, L"FI_DefaultDistortionField", FFX_RESOURCE_TYPE_TEXTURE2D, FFX_RESOURCE_USAGE_READ_ONLY, + FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, 1, 1, 1, FFX_RESOURCE_FLAGS_NONE, FfxResourceInitData::FfxResourceInitBuffer(sizeof(defaultDistortionFieldData), defaultDistortionFieldData) }, }; // clear the SRV resources to NULL. @@ -489,6 +494,7 @@ static FfxErrorCode frameinterpolationRelease(FfxFrameInterpolationContext_Priva context->uavResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS] = {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_NULL}; context->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME] = {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_NULL}; context->uavResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME] = {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_NULL}; + context->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DISTORTION_FIELD] = {FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_NULL}; // Release the copy resources for those that had init data ffxSafeReleaseCopyResource(&context->contextDescription.backendInterface, context->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNTERS], context->effectContextId); @@ -857,6 +863,18 @@ FFX_API FfxErrorCode ffxFrameInterpolationDispatch(FfxFrameInterpolationContext* const float cameraAngleHorizontal = atan(tan(params->cameraFovAngleVertical / 2) * aspectRatio) * 2; contextPrivate->constants.fTanHalfFOV = tanf(cameraAngleHorizontal * 0.5f); + const bool bUseExternalDistortionFieldResource = !ffxFrameInterpolationResourceIsNull(params->distortionField); + if (bUseExternalDistortionFieldResource) + { + contextPrivate->constants.distortionFieldSize[0] = params->distortionField.description.width; + contextPrivate->constants.distortionFieldSize[1] = params->distortionField.description.height; + } + else + { + contextPrivate->constants.distortionFieldSize[0] = 1; + contextPrivate->constants.distortionFieldSize[1] = 1; + } + contextPrivate->renderDescription.cameraFar = params->cameraFar; contextPrivate->renderDescription.cameraNear = params->cameraNear; contextPrivate->renderDescription.viewSpaceToMetersFactor = (params->viewSpaceToMetersFactor > 0.0f) ? params->viewSpaceToMetersFactor : 1.0f; @@ -888,7 +906,7 @@ FFX_API FfxErrorCode ffxFrameInterpolationDispatch(FfxFrameInterpolationContext* contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS] = contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_0 + doubleBufferId]; contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME] = contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME_0 + doubleBufferId]; - // Register output as SRV and UAV + // Register output as SRV and UAV contextPrivate->contextDescription.backendInterface.fpRegisterResource(&contextPrivate->contextDescription.backendInterface, ¶ms->output, contextPrivate->effectContextId, &contextPrivate->uavResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OUTPUT]); contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OUTPUT] = contextPrivate->uavResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OUTPUT]; @@ -906,6 +924,19 @@ FFX_API FfxErrorCode ffxFrameInterpolationDispatch(FfxFrameInterpolationContext* contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OPTICAL_FLOW_VECTOR] = {}; } + if (bUseExternalDistortionFieldResource) + { + contextPrivate->contextDescription.backendInterface.fpRegisterResource( + &contextPrivate->contextDescription.backendInterface, + ¶ms->distortionField, + contextPrivate->effectContextId, + &contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DISTORTION_FIELD]); + } + else + { + contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DISTORTION_FIELD] = contextPrivate->srvResources[FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEFAULT_DISTORTION_FIELD]; + } + uint32_t displayDispatchSizeX = uint32_t(params->displaySize.width + 7) / 8; uint32_t displayDispatchSizeY = uint32_t(params->displaySize.height + 7) / 8; diff --git a/sdk/src/components/frameinterpolation/ffx_frameinterpolation_private.h b/sdk/src/components/frameinterpolation/ffx_frameinterpolation_private.h index 3ac82eee..e4c67e89 100644 --- a/sdk/src/components/frameinterpolation/ffx_frameinterpolation_private.h +++ b/sdk/src/components/frameinterpolation/ffx_frameinterpolation_private.h @@ -58,7 +58,7 @@ typedef struct FrameInterpolationConstants float deltaTime; int HUDLessAttachedFactor; - float UNUSED__[2]; + int32_t distortionFieldSize[2]; float opticalFlowScale[2]; int32_t opticalFlowBlockSize;