Skip to content

Commit 82fb88e

Browse files
committed
Added support for distortion field information
1 parent 5a26133 commit 82fb88e

File tree

34 files changed

+359
-19
lines changed

34 files changed

+359
-19
lines changed

ffx-api/include/ffx_api/ffx_framegeneration.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct ffxDispatchDescFrameGeneration
8585
void* commandList; ///< The command list on which to register render commands.
8686
struct FfxApiResource presentColor; ///< The current presentation color, this will be used as source data.
8787
struct FfxApiResource outputs[4]; ///< Destination targets (1 for each frame in numGeneratedFrames).
88+
struct FfxApiResource distortionField; ///< The distortion field data.
8889
uint32_t numGeneratedFrames; ///< The number of frames to generate from the passed in color target.
8990
bool reset; ///< A boolean value which when set to true, indicates the camera has moved discontinuously.
9091
uint32_t backbufferTransferFunction; ///< The transfer function use to convert frame generation source color data to linear RGB. One of the values from FfxApiBackbufferTransferFunction.

ffx-api/src/ffx_provider_framegeneration.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ ffxReturnCode_t ffxProvider_FrameGeneration::Dispatch(ffxContext* context, const
353353
fiDispatchDesc.renderSize.width = prepDesc->renderSize.width;
354354
fiDispatchDesc.renderSize.height = prepDesc->renderSize.height;
355355
fiDispatchDesc.output = Convert(desc->outputs[0]);
356+
fiDispatchDesc.distortionField = Convert(desc->distortionField);
356357
fiDispatchDesc.opticalFlowVector = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_VECTOR]);
357358
fiDispatchDesc.opticalFlowSceneChangeDetection = internal_context->backendInterfaceShared.fpGetResource(&internal_context->backendInterfaceShared, internal_context->sharedResources[FFX_FSR3_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_OUTPUT]);
358359
fiDispatchDesc.opticalFlowBlockSize = 8;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// This file is part of the FidelityFX SDK.
2+
//
3+
// Copyright (C) 2024 Advanced Micro Devices, Inc.
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files(the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions :
11+
//
12+
// The above copyright notice and this permission notice shall be included in
13+
// all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
// THE SOFTWARE.
22+
23+
#include "tonemappercommon.h"
24+
#include "lensdistortion.h"
25+
26+
//--------------------------------------------------------------------------------------
27+
// Texture definitions
28+
//--------------------------------------------------------------------------------------
29+
RWTexture2D<float4> OutputTexture : register(u0);
30+
31+
bool IsInsideLetterbox(int2 pixel)
32+
{
33+
if (pixel.x > LetterboxRectBase.x && pixel.y > LetterboxRectBase.y &&
34+
pixel.x < LetterboxRectBase.x + LetterboxRectSize.x &&
35+
pixel.y <= LetterboxRectBase.y + LetterboxRectSize.y)
36+
return true;
37+
38+
return false;
39+
}
40+
41+
//--------------------------------------------------------------------------------------
42+
// Main function
43+
//--------------------------------------------------------------------------------------
44+
[numthreads(NUM_THREAD_X, NUM_THREAD_Y, 1)]
45+
void MainCS(uint3 dtID : SV_DispatchThreadID)
46+
{
47+
const uint2 pixel = dtID.xy;
48+
49+
float4 distortionField = float4(0.0f, 0.0f, 0.0f, 0.0f);
50+
if (IsInsideLetterbox(pixel))
51+
{
52+
float2 uv = (pixel + 0.5f) / LetterboxRectSize;
53+
distortionField = GenerateDistortionField(uv);
54+
}
55+
OutputTexture[pixel] = distortionField;
56+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// This file is part of the FidelityFX SDK.
2+
//
3+
// Copyright (C) 2024 Advanced Micro Devices, Inc.
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files(the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions :
11+
//
12+
// The above copyright notice and this permission notice shall be included in
13+
// all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
// THE SOFTWARE.
22+
23+
#ifndef LENSDISTORTION_HLSL
24+
#define LENSDISTORTION_HLSL
25+
26+
#include "tonemappercommon.h"
27+
28+
float2 BarrelDistortion(in float2 Uv)
29+
{
30+
float2 remappedUv = (Uv * 2.0f) - 1.0f;
31+
float r2 = remappedUv.x * remappedUv.x + remappedUv.y * remappedUv.y;
32+
float2 outUv = remappedUv / (1.0f + LensDistortionStrength * r2);
33+
return (outUv + 1.0f) / 2.0f;
34+
}
35+
36+
float2 InverseBarrelDistortion(in float2 Uv)
37+
{
38+
float2 remappedUv = (Uv * 2.0f) - 1.0f;
39+
float ru2 = remappedUv.x * remappedUv.x + remappedUv.y * remappedUv.y;
40+
float num = sqrt(1.0f - 4.0f * LensDistortionStrength * ru2) - 1.0f;
41+
float denom = 2.0f * LensDistortionStrength * sqrt(ru2);
42+
float rd = -num / denom;
43+
float2 outUV = remappedUv * (rd / sqrt(ru2));
44+
return (outUV + 1.0f) / 2.0f;
45+
}
46+
47+
float2 Zoom(in float2 Uv)
48+
{
49+
float2 translatedCoord = (Uv - 0.5f) * 2.0f;
50+
translatedCoord *= (1.0f - saturate(LensDistortionZoom));
51+
return (translatedCoord + 1.0f) / 2.0f;
52+
}
53+
54+
float2 InverseZoom(in float2 Uv)
55+
{
56+
float2 translatedCoord = (Uv - 0.5f) * 2.0f;
57+
translatedCoord /= (1.0f - saturate(LensDistortionZoom));
58+
return (translatedCoord + 1.0f) / 2.0f;
59+
}
60+
61+
float4 GenerateDistortionField(in float2 Uv)
62+
{
63+
float2 xy = Zoom(BarrelDistortion(Uv)) - Uv;
64+
float2 zw = InverseBarrelDistortion(InverseZoom(Uv)) - Uv;
65+
return float4(xy, zw);
66+
}
67+
68+
float2 ApplyLensDistortion(in float2 Uv)
69+
{
70+
return Zoom(BarrelDistortion(Uv));
71+
}
72+
73+
#endif

framework/cauldron/framework/inc/shaders/tonemapping/tonemappercommon.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
// THE SOFTWARE.
2222

23+
#ifndef TONEMAPPERCOMMON_H
24+
#define TONEMAPPERCOMMON_H
25+
2326
#if __cplusplus
2427
#pragma once
2528
#include <shaders/shadercommon.h>
@@ -42,10 +45,17 @@ struct TonemapperCBData
4245
mutable uint32_t ToneMapper = 0;
4346
float DisplayMaxLuminance;
4447
DisplayMode MonitorDisplayMode;
48+
4549
Mat4 ContentToMonitorRecMatrix;
50+
4651
int32_t LetterboxRectBase[2];
4752
int32_t LetterboxRectSize[2];
53+
4854
uint32_t UseAutoExposure = 0;
55+
uint32_t LensDistortionEnabled = 0;
56+
float LensDistortionStrength = -0.2f;
57+
float LensDistortionZoom = 0.4f;
58+
4959

5060
};
5161
#else
@@ -67,5 +77,10 @@ cbuffer TonemapperCBData : register(b0)
6777
int2 LetterboxRectBase : packoffset(c5.x);
6878
int2 LetterboxRectSize : packoffset(c5.z);
6979
bool UseAutoExposure : packoffset(c6.x);
80+
bool LensDistortionEnabled : packoffset(c6.y);
81+
float LensDistortionStrength : packoffset(c6.z);
82+
float LensDistortionZoom : packoffset(c6.w);
7083
}
7184
#endif // __cplusplus
85+
86+
#endif // TONEMAPPERCOMMON_H

framework/cauldron/framework/inc/shaders/tonemapping/tonemapping.hlsl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "tonemappers.hlsl"
2424
#include "tonemappercommon.h"
2525
#include "transferfunction.h"
26+
#include "lensdistortion.h"
2627

2728
//--------------------------------------------------------------------------------------
2829
// Texture definitions
@@ -48,7 +49,14 @@ void MainCS(uint3 dtID : SV_DispatchThreadID)
4849
}
4950
else
5051
{
51-
const int2 coordInLetterbox = dtID.xy - LetterboxRectBase;
52+
int2 coordInLetterbox = dtID.xy - LetterboxRectBase;
53+
54+
if (LensDistortionEnabled)
55+
{
56+
const float2 uvInLetterbox = (coordInLetterbox + 0.5f) / LetterboxRectSize;
57+
const float2 distortedUvInLetterbox = ApplyLensDistortion(uvInLetterbox);
58+
coordInLetterbox = distortedUvInLetterbox * LetterboxRectSize;
59+
}
5260
const float4 texColor = InputTexture[coordInLetterbox];
5361

5462
const float2 autoExposure = AutomaticExposureValue[int2(0, 0)];

framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.cpp

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ void ToneMappingRenderModule::Init(const json& InitData)
6565
m_pRenderTargetOut = GetFramework()->GetRenderTexture(L"SwapChainProxy");
6666
CauldronAssert(ASSERT_CRITICAL, m_pRenderTargetOut != nullptr, L"Couldn't find the render target for the tone mapper output");
6767

68+
m_pDistortionField = GetFramework()->GetRenderTexture(L"DistortionField");
69+
6870
TextureDesc desc = TextureDesc::Tex2D(L"AutomaticExposureSpdAtomicCounter", ResourceFormat::R32_UINT, 1, 1, 1, 1, ResourceFlags::AllowUnorderedAccess);
6971
m_pAutomaticExposureSpdAtomicCounter = GetDynamicResourcePool()->CreateRenderTexture(&desc);
7072

@@ -133,6 +135,31 @@ void ToneMappingRenderModule::Init(const json& InitData)
133135
m_pAutoExposureSpdParameters->SetTextureUAV(m_pAutomaticExposureMips5, ViewDimension::Texture2D, 2);
134136
m_pAutoExposureSpdParameters->SetTextureUAV(m_pAutomaticExposureValue, ViewDimension::Texture2D, 3);
135137

138+
{
139+
// Init build distortion field pipeline
140+
RootSignatureDesc buildDistortionFieldSignatureDesc;
141+
buildDistortionFieldSignatureDesc.AddConstantBufferView(0, ShaderBindStage::Compute, 1);
142+
buildDistortionFieldSignatureDesc.AddTextureUAVSet(0, ShaderBindStage::Compute, 1);
143+
m_pBuildDistortionFieldRootSignature = RootSignature::CreateRootSignature(L"BuildDistortionFieldRenderPass_RootSignature", buildDistortionFieldSignatureDesc);
144+
145+
// Setup the pipeline object
146+
PipelineDesc buildDistortionFieldPsoDesc;
147+
buildDistortionFieldPsoDesc.SetRootSignature(m_pBuildDistortionFieldRootSignature);
148+
149+
// Setup the shaders to build on the pipeline object
150+
shaderPath = L"builddistortionfield.hlsl";
151+
152+
DefineList buildDistortionFieldDefineList;
153+
buildDistortionFieldDefineList.insert(std::make_pair(L"NUM_THREAD_X", std::to_wstring(g_NumThreadX)));
154+
buildDistortionFieldDefineList.insert(std::make_pair(L"NUM_THREAD_Y", std::to_wstring(g_NumThreadY)));
155+
buildDistortionFieldPsoDesc.AddShaderDesc(ShaderBuildDesc::Compute(shaderPath.c_str(), L"MainCS", ShaderModel::SM6_0, &buildDistortionFieldDefineList));
156+
157+
m_pBuildDistortionFieldPipelineObj = PipelineObject::CreatePipelineObject(L"BuildDistortionFieldRenderPass_PipelineObj", buildDistortionFieldPsoDesc);
158+
159+
m_pBuildDistortionFieldParameters = ParameterSet::CreateParameterSet(m_pBuildDistortionFieldRootSignature);
160+
m_pBuildDistortionFieldParameters->SetRootConstantBufferResource(GetDynamicBufferPool()->GetResource(), sizeof(TonemapperCBData), 0);
161+
m_pBuildDistortionFieldParameters->SetTextureUAV(m_pDistortionField, ViewDimension::Texture2D, 0);
162+
}
136163
// Init tonemapper
137164
// root signature
138165
RootSignatureDesc tonemapperSignatureDesc;
@@ -182,6 +209,10 @@ void ToneMappingRenderModule::Init(const json& InitData)
182209
}
183210
);
184211
uiSection->RegisterUIElement<UICheckBox>("AutoExposure", (bool&)m_TonemapperConstantData.UseAutoExposure);
212+
213+
uiSection->RegisterUIElement<UICheckBox>("Lens Distortion Enable", (bool&)m_TonemapperConstantData.LensDistortionEnabled);
214+
uiSection->RegisterUIElement<UISlider<float>>("Lens Distortion Strength", m_TonemapperConstantData.LensDistortionStrength, -1.f, 1.f, m_TonemapperConstantData.LensDistortionEnabled, nullptr, true);
215+
uiSection->RegisterUIElement<UISlider<float>>("Lens Distortion Zoom", m_TonemapperConstantData.LensDistortionZoom, 0.f, 1.f, m_TonemapperConstantData.LensDistortionEnabled, nullptr, true);
185216
}
186217

187218
// We are now ready for use
@@ -194,6 +225,10 @@ ToneMappingRenderModule::~ToneMappingRenderModule()
194225
delete m_pAutoExposureSpdPipelineObj;
195226
delete m_pAutoExposureSpdParameters;
196227

228+
delete m_pBuildDistortionFieldRootSignature;
229+
delete m_pBuildDistortionFieldPipelineObj;
230+
delete m_pBuildDistortionFieldParameters;
231+
197232
delete m_pTonemapperRootSignature;
198233
delete m_pTonemapperPipelineObj;
199234
delete m_pTonemapperParameters;
@@ -238,7 +273,7 @@ void ToneMappingRenderModule::Execute(double deltaTime, CommandList* pCmdList)
238273

239274
Dispatch(pCmdList, m_DispatchThreadGroupCountXY[0], m_DispatchThreadGroupCountXY[1], 1);
240275
}
241-
276+
242277
{
243278
GPUScopedProfileCapture tonemappingMarker(pCmdList, L"ToneMapping");
244279

@@ -302,4 +337,33 @@ void ToneMappingRenderModule::Execute(double deltaTime, CommandList* pCmdList)
302337
ResourceState::NonPixelShaderResource | ResourceState::PixelShaderResource);
303338
ResourceBarrier(pCmdList, 1, &barrier);
304339
}
340+
341+
if (m_TonemapperConstantData.LensDistortionEnabled)
342+
{
343+
GPUScopedProfileCapture distortionFieldMarker(pCmdList, L"Build Distortion Field");
344+
345+
Barrier barrierToWrite = Barrier::Transition(m_pDistortionField->GetResource(),
346+
ResourceState::NonPixelShaderResource | ResourceState::PixelShaderResource,
347+
ResourceState::UnorderedAccess);
348+
ResourceBarrier(pCmdList, 1, &barrierToWrite);
349+
350+
// Allocate a dynamic constant buffer and set
351+
BufferAddressInfo bufferInfo = GetDynamicBufferPool()->AllocConstantBuffer(sizeof(TonemapperCBData), &m_TonemapperConstantData);
352+
m_pBuildDistortionFieldParameters->UpdateRootConstantBuffer(&bufferInfo, 0);
353+
354+
// bind all the parameters
355+
m_pBuildDistortionFieldParameters->Bind(pCmdList, m_pBuildDistortionFieldPipelineObj);
356+
357+
// Set pipeline and dispatch
358+
SetPipelineState(pCmdList, m_pBuildDistortionFieldPipelineObj);
359+
360+
const uint32_t numGroupX = DivideRoundingUp(m_pDistortionField->GetDesc().Width, g_NumThreadX);
361+
const uint32_t numGroupY = DivideRoundingUp(m_pDistortionField->GetDesc().Height, g_NumThreadY);
362+
Dispatch(pCmdList, numGroupX, numGroupY, 1);
363+
364+
Barrier barrierToRead = Barrier::Transition(m_pDistortionField->GetResource(),
365+
ResourceState::UnorderedAccess,
366+
ResourceState::NonPixelShaderResource | ResourceState::PixelShaderResource);
367+
ResourceBarrier(pCmdList, 1, &barrierToRead);
368+
}
305369
}

framework/cauldron/framework/src/render/rendermodules/tonemapping/tonemappingrendermodule.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,18 @@ class ToneMappingRenderModule : public cauldron::RenderModule
5757
// Constant data
5858
uint32_t m_DispatchThreadGroupCountXY[2];
5959

60-
AutoExposureSpdConstants m_AutoExposureSpdConstants;
61-
TonemapperCBData m_TonemapperConstantData;
60+
AutoExposureSpdConstants m_AutoExposureSpdConstants;
61+
TonemapperCBData m_TonemapperConstantData;
6262

6363
// common
6464
cauldron::RootSignature* m_pAutoExposureSpdRootSignature = nullptr;
6565
cauldron::PipelineObject* m_pAutoExposureSpdPipelineObj = nullptr;
6666
cauldron::ParameterSet* m_pAutoExposureSpdParameters = nullptr;
6767

68+
cauldron::RootSignature* m_pBuildDistortionFieldRootSignature = nullptr;
69+
cauldron::PipelineObject* m_pBuildDistortionFieldPipelineObj = nullptr;
70+
cauldron::ParameterSet* m_pBuildDistortionFieldParameters = nullptr;
71+
6872
cauldron::RootSignature* m_pTonemapperRootSignature = nullptr;
6973
const cauldron::RasterView* m_pRasterView = nullptr;
7074
cauldron::PipelineObject* m_pTonemapperPipelineObj = nullptr;
@@ -77,5 +81,6 @@ class ToneMappingRenderModule : public cauldron::RenderModule
7781
cauldron::SamplerDesc m_LinearSamplerDesc;
7882

7983
const cauldron::Texture* m_pRenderTargetIn = nullptr;
80-
const cauldron::Texture* m_pRenderTargetOut = nullptr;
84+
const cauldron::Texture* m_pRenderTargetOut = nullptr;
85+
const cauldron::Texture* m_pDistortionField = nullptr;
8186
};

samples/fsrapi/config/fsrapiconfig.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
"MotionVectorGeneration": "GBufferRenderModule",
44

55
"RenderResources": {
6+
"DistortionField": {
7+
"Format": "RGBA16_FLOAT",
8+
"AllowUAV": true,
9+
"RenderResolution": false
10+
},
611
"ReactiveMask": {
712
"Format": "R8_UNORM",
813
"AllowUAV": true,

0 commit comments

Comments
 (0)