Skip to content

Enhanced the VRS implementation to support foveated rendering #142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified docs/samples/media/variable-shading/variable-shading.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/samples/media/variable-shading/variable-shading.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion docs/samples/variable-shading.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ The sample contains various UI elements to help you explore the techniques it de
| **PerDraw VRS** | `1x1, 1x2, 2x1, 2x2` | Shading rate value. Additional shading rates are 2x4, 4x2, 4x4. |
| **ShadingRateImage Enabled** | `Checked/Unchecked` | Enable/Disable Tier 2 VRS control image. |
| **ShadingRateImage Combiner** | `Checked/Unchecked` | The options for each combiner are: passthrough the previous state (i.e. disable the current stage), override (ignore previous stages), min, max and sum. |
| **VRS Algorithm** | `Luminance and Motion Vectors, Foveated Rendering, Combined (Max)` | The technique used to generate the shading rate image. |
| **VRS variance Threshold** | `0.0 - 1.0` | Defines a value against which luminance variance gets compared in the compute shader generating the VRS image. |
| **VRS Motion Factor** | `0.0 - 1.0` | Sets a factor by which the motion of the pixel since the last frame gets scaled to modify the shading rate. |
| **ShadingRateImage Overlay** | `Checked/Unchecked` | Enable/Disable ShadingRateImage overlay, a debug image over the rendered scene. |

<h2>Setting up Variable Shading</h2>

The Variable Shading compute shader takes as input the linear color buffer produced by the geometry rendering passes, and motion vectors buffer produced before geometry rendering passes. Final VRS control image is written to output buffer passed from setup.
The Variable Shading compute shader takes as input the linear color buffer produced by the geometry rendering passes, and motion vectors buffer produced before geometry rendering passes. It also takes as input the center and radii for the foveated rendering regions. Final VRS control image is written to output buffer passed from setup.

Include the interface for the backend of the VRS API.

Expand Down
5 changes: 4 additions & 1 deletion docs/techniques/variable-shading.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ FidelityFX Variable Shading (VRS) provides a similar way to reduce the number of

One way to think about how VRS works is to think of MSAA: if a 4K frame is rendered with 2x2 VRS for everything, the required computational power and the final quality of the image would be comparable to rendering a 1080p image with 4x MSAA enabled. However, VRS provides additional features to enable more fine-grained control over which parts of the frame should get rendered with lower resolution.

FidelityFX Variable Shading (VRS) also gives the option to implement Foveated Rendering by significanly reducing the number of pixel shading executions at the outer periphery of where the user is looking, taking advantage of the user not noticing the loss of visual quality in such regions. This can thus be paired with an eye tracker, whether built in a VR headset, a dedicated hardware or a webcam based software.

<h2>Implementing Variable Shading</h2>

<h3>Cases allowing VRS</h3>
Expand All @@ -24,8 +26,9 @@ image:
- Some objects may get distorted or blurred by being behind haze or semi-transparent objects like water or frosted glass.
- Some objects might be known to have little detail variance (such as rendering for toon shaded games) or due to being in very dark parts of the scene (e.g. the unlit or shadowed parts of objects in scenes with little ambient light).
- In fast moving scenes, high framerate and low input lag are important, but small details are less likely to get noticed by the player, so aggressively using VRS can help to achieve the performance goals.
- When using an eye tracking device, one can establish where the user is looking, and can decrease the visual quality away from that area without being noticeable.

In addition to the cases mentioned above, some pixels might be known to be of little interest to the player, either through eye-tracking (foveated rendering) or other systems, or because the game design aims to steer the focus of the player to certain parts of the screen. As an example, the game might choose to reduce the shading rate on the background geometry but make sure all enemies are rendered at highest quality.
In addition to the cases mentioned above, some pixels might be known to be of little interest to the player, either through eye-tracking or other systems, or because the game design aims to steer the focus of the player to certain parts of the screen. As an example, the game might choose to reduce the shading rate on the background geometry but make sure all enemies are rendered at highest quality.

Due to saving computational power by focusing usage of GPU resources where it matters most, VRS can be used to make sure target frame times are achieved (similar to dynamic resolution scaling but with more fine-grained control over where detail needs to be preserved), as well as for power saving on portable devices without noticeably sacrificing image quality.

Expand Down
30 changes: 30 additions & 0 deletions samples/vrs/vrsrendermodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,21 @@ void VRSRenderModule::BuildUI()
}
);

const char* algorithmOptions[] = {"Luminance and Motion Vectors", "Foveated Rendering", "Combined (Max)"};
comboOptions.clear();
for (int32_t i = 0; i < _countof(algorithmOptions); ++i)
{
comboOptions.push_back(algorithmOptions[i]);
}

uiSection->RegisterUIElement<UICombo>(
"VRS Algorithm",
(int32_t&)m_ShadingRateImageAlgorithmIndex,
std::move(comboOptions),
m_ShadingRateImageEnabled,
[this](int32_t cur, int32_t old) {}
);

uiSection->RegisterUIElement<UISlider<float>>("VRS variance Threshold", m_VRSThreshold, 0.f, 0.1f, m_ShadingRateImageEnabled);
uiSection->RegisterUIElement<UISlider<float>>("VRS Motion Factor", m_VRSMotionFactor, 0.f, 0.1f, m_ShadingRateImageEnabled);

Expand Down Expand Up @@ -691,8 +706,17 @@ void VRSRenderModule::ExecuteVRSImageGen(double deltaTime, cauldron::CommandList
uint32_t width = GetFramework()->GetResolutionInfo().RenderWidth;
uint32_t height = GetFramework()->GetResolutionInfo().RenderHeight;

uint32_t vrsAlgorithm;
if (m_ShadingRateImageAlgorithmIndex == 0)
vrsAlgorithm = FFX_VARIABLESHADING_IMAGE_ALGORITHM_LUMINANCE_AND_MOTION_VECTORS;
else if (m_ShadingRateImageAlgorithmIndex == 1)
vrsAlgorithm = FFX_VARIABLESHADING_IMAGE_ALGORITHM_FOVEATED;
else
vrsAlgorithm = FFX_VARIABLESHADING_IMAGE_ALGORITHM_LUMINANCE_AND_MOTION_VECTORS | FFX_VARIABLESHADING_IMAGE_ALGORITHM_FOVEATED;

FfxVrsDispatchDescription dispatchParameters = {};
dispatchParameters.commandList = SDKWrapper::ffxGetCommandList(pCmdList);
dispatchParameters.vrsAlgorithm = vrsAlgorithm;
dispatchParameters.output = SDKWrapper::ffxGetResource(m_pVRSTexture->GetResource(), L"VRSImage", FFX_RESOURCE_STATE_UNORDERED_ACCESS);
dispatchParameters.historyColor = SDKWrapper::ffxGetResource(m_pHistoryColorBuffer->GetResource(), L"HistoryColorBuffer", FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
dispatchParameters.motionVectors = SDKWrapper::ffxGetResource(m_pMotionVectors->GetResource(), L"VRSMotionVectorsTarget", FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ);
Expand All @@ -702,6 +726,12 @@ void VRSRenderModule::ExecuteVRSImageGen(double deltaTime, cauldron::CommandList
dispatchParameters.renderSize = {width, height};
dispatchParameters.motionVectorScale.x = -1.f;
dispatchParameters.motionVectorScale.y = -1.f;
dispatchParameters.foveationCenter.x = m_VRSFoveationCenter.x * width;
dispatchParameters.foveationCenter.y = m_VRSFoveationCenter.y * height;
dispatchParameters.foveationRadiiSquared.radius1x1 = (m_VRSFovRadii.radius1x1 * width) * (m_VRSFovRadii.radius1x1 * width);
dispatchParameters.foveationRadiiSquared.radius1x2 = (m_VRSFovRadii.radius1x2 * width) * (m_VRSFovRadii.radius1x2 * width);
dispatchParameters.foveationRadiiSquared.radius2x2 = (m_VRSFovRadii.radius2x2 * width) * (m_VRSFovRadii.radius2x2 * width);
dispatchParameters.foveationRadiiSquared.radius2x4 = (m_VRSFovRadii.radius2x4 * width) * (m_VRSFovRadii.radius2x4 * width);

// Disabled until remaining things are fixes
FfxErrorCode errorCode = ffxVrsContextDispatch(&m_VRSContext, &dispatchParameters);
Expand Down
3 changes: 3 additions & 0 deletions samples/vrs/vrsrendermodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,13 @@ class VRSRenderModule : public cauldron::RenderModule, public cauldron::ContentL
uint32_t m_ShadingRateIndex = 0;
uint32_t m_ShadingRateCombinerIndex = 0;
bool m_EnableShadingRateImage = false;
uint32_t m_ShadingRateImageAlgorithmIndex = 0;
bool m_AllowAdditionalShadingRates = false;
uint32_t m_VRSTierSupported = 0;
float m_VRSThreshold = 0.015f;
float m_VRSMotionFactor = 0.01f;
FfxFloatCoords2D m_VRSFoveationCenter{0.5f, 0.5f};
FfxVrsFovRadii m_VRSFovRadii{0.2f, 0.3f, 0.4f, 0.5f};

bool m_VariableShadingEnabled = false;
bool m_ShadingRateImageEnabled = false;
Expand Down
93 changes: 93 additions & 0 deletions sdk/include/FidelityFX/gpu/vrs/ffx_variable_shading.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#define FFX_CPU
#include <FidelityFX/gpu/ffx_core.h>

FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_IMAGE_ALGORITHM_LUMINANCE_AND_MOTION_VECTORS = 0x1;
FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_IMAGE_ALGORITHM_FOVEATED = 0x2;

FFX_STATIC void ffxVariableShadingGetDispatchInfo(
const FfxDimensions2D resolution, const FfxUInt32 tileSize, const bool useAditionalShadingRates, FfxUInt32& numThreadGroupsX, FfxUInt32& numThreadGroupsY)
{
Expand Down Expand Up @@ -61,6 +64,9 @@ FFX_STATIC void ffxVariableShadingGetDispatchInfo(
}
#elif defined(FFX_GPU)

FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_IMAGE_ALGORITHM_LUMINANCE_AND_MOTION_VECTORS = 0x1;
FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_IMAGE_ALGORITHM_FOVEATED = 0x2;

// Forward declaration of functions that need to be implemented by shader code using this technique
FfxFloat32 ReadLuminance(FfxInt32x2 pos);
FfxFloat32x2 ReadMotionVec2D(FfxInt32x2 pos);
Expand All @@ -70,6 +76,8 @@ FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_RATE1D_1X = 0x0;
FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_RATE1D_2X = 0x1;
FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_RATE1D_4X = 0x2;
#define FFX_VARIABLESHADING_MAKE_SHADING_RATE(x,y) ((x << 2) | (y))
#define FFX_VARIABLESHADING_SHADING_RATE_2D_MAX(xy, wz) \
FFX_VARIABLESHADING_MAKE_SHADING_RATE(max(xy >> 2, wz >> 2), max(xy & 0x3,wz & 0x3))

FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_RATE_1X1 = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_1X, FFX_VARIABLESHADING_RATE1D_1X); // 0;
FFX_STATIC const FfxUInt32 FFX_VARIABLESHADING_RATE_1X2 = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_1X, FFX_VARIABLESHADING_RATE1D_2X); // 0x1;
Expand All @@ -91,6 +99,7 @@ FFX_STATIC const FfxUInt32 FFX_VariableShading_ThreadCount1D = 16;
FFX_STATIC const FfxUInt32 FFX_VariableShading_NumBlocks1D = 1;
#endif
FFX_STATIC const FfxUInt32 FFX_VariableShading_SampleCount1D = FFX_VariableShading_ThreadCount1D + 2;
FFX_STATIC const FfxUInt32 FFX_VariableShading_TileCenterOffset1D = FFX_VARIABLESHADING_TILESIZE >> 1 - 1;

FFX_GROUPSHARED FfxUInt32 FFX_VariableShading_LdsGroupReduce;

Expand All @@ -107,6 +116,7 @@ FFX_STATIC const FfxUInt32 FFX_VariableShading_ThreadCount1D = 8;
FFX_STATIC const FfxUInt32 FFX_VariableShading_NumBlocks1D = 32 / FFX_VARIABLESHADING_TILESIZE;
FFX_STATIC const FfxUInt32 FFX_VariableShading_TilesPerGroup = FFX_VariableShading_NumBlocks1D * FFX_VariableShading_NumBlocks1D;
FFX_STATIC const FfxUInt32 FFX_VariableShading_SampleCount1D = FFX_VariableShading_ThreadCount1D + 2;
FFX_STATIC const FfxUInt32 FFX_VariableShading_TileCenterOffset1D = FFX_VARIABLESHADING_TILESIZE >> 1 - 1;

FFX_GROUPSHARED FfxUInt32 FFX_VariableShading_LdsGroupReduce[FFX_VariableShading_TilesPerGroup];

Expand All @@ -118,6 +128,46 @@ FFX_STATIC const FfxUInt32 FFX_VariableShading_NumBlocks = FFX_VariableShading_N
FFX_GROUPSHARED FfxUInt32 FFX_VariableShading_LdsShadingRate[FFX_VariableShading_SampleCount];
#endif

FfxUInt32 VrsComputeFoveatedShadingRate(FfxUInt32x3 Gid, FfxUInt32x3 Gtid, FfxUInt32 Gidx)
{
FfxFloat32x2 tileVRSImageCoords = FfxFloat32x2(Gid.xy * FFX_VariableShading_NumBlocks1D + FfxUInt32x2(Gidx / FFX_VariableShading_NumBlocks1D, Gidx % FFX_VariableShading_NumBlocks1D));
FfxFloat32x2 tileRenderingTargetCoords = FfxFloat32x2(tileVRSImageCoords.x * FFX_VARIABLESHADING_TILESIZE, tileVRSImageCoords.y * FFX_VARIABLESHADING_TILESIZE) + FfxFloat32x2(FFX_VariableShading_TileCenterOffset1D, FFX_VariableShading_TileCenterOffset1D);
FfxFloat32x2 dxy = tileRenderingTargetCoords - FoveationCenter();
FfxFloat32 distSquared = dot(dxy, dxy);

FfxUInt32 shadingRate;
if (distSquared < FoveationRadiiSquared().x) // 1X1
{
shadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_1X, FFX_VARIABLESHADING_RATE1D_1X);
}
else if (distSquared < FoveationRadiiSquared().y) // 1X2 or 2X1
{
bool horizontal = abs(dxy.x) > abs(dxy.y);
shadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(horizontal ? FFX_VARIABLESHADING_RATE1D_1X : FFX_VARIABLESHADING_RATE1D_2X, horizontal ? FFX_VARIABLESHADING_RATE1D_2X : FFX_VARIABLESHADING_RATE1D_1X);
}
#if !defined FFX_VARIABLESHADING_ADDITIONALSHADINGRATES
else // 2X2
{
shadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_2X, FFX_VARIABLESHADING_RATE1D_2X);
}
#else // if defined FFX_VARIABLESHADING_ADDITIONALSHADINGRATES
else if (distSquared < FoveationRadiiSquared().z) // 2X2
{
shadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_2X, FFX_VARIABLESHADING_RATE1D_2X);
}
else if (distSquared < FoveationRadiiSquared().w) // 2X4 or 4X2
{
bool horizontal = abs(dxy.x) > abs(dxy.y);
shadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(horizontal ? FFX_VARIABLESHADING_RATE1D_2X : FFX_VARIABLESHADING_RATE1D_4X, horizontal ? FFX_VARIABLESHADING_RATE1D_4X : FFX_VARIABLESHADING_RATE1D_2X);
}
else // 4X4
{
shadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_4X, FFX_VARIABLESHADING_RATE1D_4X);
}
#endif
return shadingRate;
}

// Read luminance value from previous frame's color buffer.
FfxFloat32 VrsGetLuminance(FfxInt32x2 pos)
{
Expand Down Expand Up @@ -152,6 +202,24 @@ FfxInt32 VrsFlattenLdsOffset(FfxInt32x2 coord)
/// @ingroup FfxGPUVrs
void VrsGenerateVrsImage(FfxUInt32x3 Gid, FfxUInt32x3 Gtid, FfxUInt32 Gidx)
{
FfxUInt32 foveatedShadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_1X, FFX_VARIABLESHADING_RATE1D_1X);
if ((VrsAlgorithm() & FFX_VARIABLESHADING_IMAGE_ALGORITHM_FOVEATED) != 0)
{
foveatedShadingRate = VrsComputeFoveatedShadingRate(Gid, Gtid, Gidx);
}

// if motion based algorithm is disabled, or if foveation is returning coarsest rate already, early exit
if (((VrsAlgorithm() & FFX_VARIABLESHADING_IMAGE_ALGORITHM_LUMINANCE_AND_MOTION_VECTORS) == 0) ||
(foveatedShadingRate == FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_2X, FFX_VARIABLESHADING_RATE1D_2X)))
{
if (Gidx < FFX_VariableShading_NumBlocks)
{
WriteVrsImage(
FfxInt32x2(Gid.xy * FFX_VariableShading_NumBlocks1D + FfxUInt32x2(Gidx / FFX_VariableShading_NumBlocks1D, Gidx % FFX_VariableShading_NumBlocks1D)), foveatedShadingRate);
}
return;
}

FfxInt32x2 tileOffset = FfxInt32x2(Gid.xy * FFX_VariableShading_ThreadCount1D * 2);
FfxInt32x2 baseOffset = tileOffset + FfxInt32x2(-2, -2);
FfxUInt32 index = Gidx;
Expand Down Expand Up @@ -315,6 +383,9 @@ void VrsGenerateVrsImage(FfxUInt32x3 Gid, FfxUInt32x3 Gtid, FfxUInt32 Gidx)
shadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE((varH > VarianceCutoff()) ? FFX_VARIABLESHADING_RATE1D_1X : FFX_VARIABLESHADING_RATE1D_2X, FFX_VARIABLESHADING_RATE1D_1X);
}
}

shadingRate = FFX_VARIABLESHADING_SHADING_RATE_2D_MAX(shadingRate, foveatedShadingRate);

// Store
WriteVrsImage(
FfxInt32x2(Gid.xy * FFX_VariableShading_NumBlocks1D + FfxUInt32x2(Gidx / FFX_VariableShading_NumBlocks1D, Gidx % FFX_VariableShading_NumBlocks1D)), shadingRate);
Expand All @@ -333,6 +404,24 @@ void VrsGenerateVrsImage(FfxUInt32x3 Gid, FfxUInt32x3 Gtid, FfxUInt32 Gidx)
/// @ingroup FfxGPUVrs
void VrsGenerateVrsImage(FfxUInt32x3 Gid, FfxUInt32x3 Gtid, FfxUInt32 Gidx)
{
FfxUInt32 foveatedShadingRate = FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_1X, FFX_VARIABLESHADING_RATE1D_1X);
if ((VrsAlgorithm() & FFX_VARIABLESHADING_IMAGE_ALGORITHM_FOVEATED) != 0)
{
foveatedShadingRate = VrsComputeFoveatedShadingRate(Gid, Gtid, Gidx);
}

// if motion based algorithm is disabled, or if foveation is returning coarsest rate already, early exit
if (((VrsAlgorithm() & FFX_VARIABLESHADING_IMAGE_ALGORITHM_LUMINANCE_AND_MOTION_VECTORS) == 0) ||
(foveatedShadingRate == FFX_VARIABLESHADING_MAKE_SHADING_RATE(FFX_VARIABLESHADING_RATE1D_4X, FFX_VARIABLESHADING_RATE1D_4X)))
{
if (Gidx < FFX_VariableShading_TilesPerGroup)
{
WriteVrsImage(
FfxInt32x2(Gid.xy * FFX_VariableShading_NumBlocks1D + FfxUInt32x2(Gidx / FFX_VariableShading_NumBlocks1D, Gidx % FFX_VariableShading_NumBlocks1D)), foveatedShadingRate);
}
return;
}

FfxInt32x2 tileOffset = FfxInt32x2(Gid.xy * FFX_VariableShading_ThreadCount1D * 4);
FfxInt32x2 baseOffset = tileOffset;
FfxUInt32 index = Gidx;
Expand Down Expand Up @@ -469,6 +558,8 @@ void VrsGenerateVrsImage(FfxUInt32x3 Gid, FfxUInt32x3 Gtid, FfxUInt32 Gidx)
// write out final rates
if (Gidx < FFX_VariableShading_TilesPerGroup)
{
FFX_VariableShading_LdsGroupReduce[Gidx] = FFX_VARIABLESHADING_SHADING_RATE_2D_MAX(FFX_VariableShading_LdsGroupReduce[Gidx], foveatedShadingRate);

WriteVrsImage(
FfxInt32x2(Gid.xy * FFX_VariableShading_NumBlocks1D + FfxUInt32x2(Gidx / FFX_VariableShading_NumBlocks1D, Gidx % FFX_VariableShading_NumBlocks1D)),
FFX_VariableShading_LdsGroupReduce[Gidx]);
Expand All @@ -477,6 +568,8 @@ void VrsGenerateVrsImage(FfxUInt32x3 Gid, FfxUInt32x3 Gtid, FfxUInt32 Gidx)
// write out final rates
if (Gidx < FFX_VariableShading_TilesPerGroup)
{
shadingRate[Gidx] = FFX_VARIABLESHADING_SHADING_RATE_2D_MAX(shadingRate[Gidx], foveatedShadingRate);

WriteVrsImage(
FfxInt32x2(Gid.xy * FFX_VariableShading_NumBlocks1D + FfxUInt32x2(Gidx / FFX_VariableShading_NumBlocks1D, Gidx % FFX_VariableShading_NumBlocks1D)),
shadingRate[Gidx]);
Expand Down
30 changes: 30 additions & 0 deletions sdk/include/FidelityFX/gpu/vrs/ffx_vrs_callbacks_glsl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@
layout(set = 0, binding = VRS_BIND_CB_VRS, std140) uniform cbVRS_t
{
FfxFloat32x2 motionVectorScale;
FfxFloat32x2 foveationCenter;
FfxFloat32x4 foveationRadiiSquared;
FfxFloat32 varianceCutoff;
FfxFloat32 motionFactor;
FfxInt32x2 resolution;
FfxUInt32 tileSize;
FfxUInt32 vrsAlgorithm;
} cbVRS;

#endif
Expand Down Expand Up @@ -86,6 +89,33 @@ FfxFloat32x2 MotionVectorScale()
#endif
}

FfxFloat32x2 FoveationCenter()
{
#if defined(VRS_BIND_CB_VRS)
return cbVRS.foveationCenter;
#else
return FfxFloat32x2(0.0f);
#endif
}

FfxFloat32x4 FoveationRadiiSquared()
{
#if defined(VRS_BIND_CB_VRS)
return cbVRS.foveationRadiiSquared;
#else
return FfxFloat32x4(0.0f);
#endif
}

FfxUInt32 VrsAlgorithm()
{
#if defined(VRS_BIND_CB_VRS)
return cbVRS.vrsAlgorithm;
#else
return 0;
#endif
}

// SRVs
#if defined VRS_BIND_SRV_INPUT_COLOR
layout (set = 0, binding = VRS_BIND_SRV_INPUT_COLOR) uniform texture2D r_input_color;
Expand Down
Loading