跳至内容

FidelityFX Super Resolution 4.0.2 (FSR4) - 升频器

Screenshot

AMD FidelityFX Super Resolution 4 是一款高级放大解决方案,它利用最先进的机器学习算法,从低分辨率输入生成高质量、高分辨率的帧。

目录

引言

FidelityFX Super Resolution 4(简称 FSR 4)是一种尖端的游戏放大技术,它利用机器学习将低分辨率帧放大到更高的分辨率。该算法通过分析多帧的时间和空间信息来重建细节并提高图像质量。这种方法有助于开发者在不显着影响性能的情况下实现更高的感知分辨率和视觉保真度,因此非常适合对质量和效率都有要求的实时应用。

着色语言要求

  • HLSL
    • CS_6_4

集成指南

FidelityFX Super Resolution 4 需要使用 FidelityFX API 进行集成,并使用二进制分发版。

有关一般的集成指南,请参阅 FidelityFX Super Resolution 3 文档。以下是 FSR4 的具体建议。

输入资源 部分所述,确保提供给 FSR 的输入颜色为 LINEAR COLORSPACE 非常重要。如果无法做到这一点,FSR API 允许在创建上下文时设置 FFX_UPSCALE_ENABLE_NON_LINEAR_COLORSPACE 标志。在这种情况下,图像质量可能会有所改善。

缩放模式

为了方便最终用户,FSR API 提供了一些命名预设的缩放比例。

画质每维缩放因子
原生 AA1.0x
画质1.5x
平衡1.7x
性能2.0x
超高性能3.0x

我们强烈建议应用程序在其用户界面中使用一致的命名和缩放比例。这是为了确保你的应用程序的用户能够获得与其他使用 FSR 的应用程序相同的用户体验。

性能

根据你的目标硬件和操作系统配置,FSR 将以不同的性能水平运行。下面是 RX 9070XT 在性能模式下运行 FSR4 的参考性能数据。从较低分辨率放大比从较高分辨率放大略快,但性能主要受 FSR 放大到的目标分辨率限制。

目标分辨率微秒 (us)
3840x21601316us
1920x1080352us

内存要求

使用 FSR 需要分配一些额外的 GPU 本地内存供 GPU 使用。使用 FSR API 时,此内存会在创建 FSR 上下文时分配,并通过构成后端接口的回调系列进行分配。此内存用于存储 FSR 算法计算的中间表面以及在应用程序的许多帧之间保持持久的表面。下表包括 FSR 在各种操作条件下使用的内存量。

分辨率工作集 (MB)
7680x43201274MB
3840x2160318MB
1920x108081MB

数据为近似值,使用 RX 9070XT GPU 四舍五入到最接近的 MB,并且可能会发生变化。

应用程序可以在创建上下文后,通过调用 ffxQuery(传入有效上下文)和 ffxQueryDescUpscaleGetGPUMemoryUsage 来获取 FSR 所需的 GPU 本地内存量。

应用程序可以在创建上下文之前,通过调用 ffxQuery(传入 NULL 上下文)并填写 ffxQueryDescUpscaleGetGPUMemoryUsageV2 来获取默认 FSR 版本所需的 GPU 本地内存量。要获取不同放大器版本的内存需求信息,请另外链接 ffxOverrideVersion

有关如何调用 Query 的代码示例,请参阅。

输入资源

下表列出了 FSR 所需的核心输入集。

分辨率列指示数据是应该为“渲染”分辨率还是“呈现”分辨率。“渲染”分辨率表示资源应与应用程序进行渲染的分辨率匹配。反之,“呈现”分辨率表示目标的解决方案应与要呈现给用户的分辨率匹配。所有资源均来自当前渲染帧。对于 DirectX(R)12 应用程序,在调用 ffxDispatchDescUpscale 之前,所有输入资源都应转换为 D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE 状态。

名称分辨率格式类型说明
颜色缓冲区渲染应用程序指定纹理由应用程序提供的当前帧的渲染分辨率颜色缓冲区。颜色缓冲区的内​​容应始终为 Linear Colorspace。如果无法做到这一点,则应在 flags 字段的 ffxCreateContextDescUpscale 结构中设置 FFX_UPSCALE_ENABLE_NON_LINEAR_COLORSPACE 标志。
深度缓冲区渲染应用程序指定 (1x FLOAT)纹理由应用程序提供的当前帧的渲染分辨率深度缓冲区。数据应提供为单个浮点值,其精度由应用程序控制。深度缓冲区的配置应通过 flags 字段的 ffxCreateContextDescUpscale 结构告知 FSR。如果你的深度缓冲区是反转的(即 [1..0] 范围),则应设置 FFX_UPSCALE_ENABLE_DEPTH_INVERTED 标志。
运动矢量渲染或呈现应用程序指定 (2x FLOAT)纹理由应用程序提供的当前帧的 2D 运动矢量,范围为 [<-width, -height> … <width, height>]。如果你的应用程序使用不同的范围渲染运动矢量,则可以使用 motionVectorScale 字段的 ffxDispatchDescUpscale 结构来调整它们以匹配 FSR 的预期范围。在许多情况下,FSR 内部使用 16 位量来表示运动矢量,这意味着虽然可以提供更高精度的运动矢量,但 FSR 将无法从中受益。运动矢量缓冲区的分辨率应等于渲染分辨率,除非在创建 flags 字段的 ffxCreateContextDescUpscale 结构中设置了 FFX_UPSCALE_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS 标志,在这种情况下,它应等于呈现分辨率。
曝光1x1R32_FLOAT纹理一个 1x1 的纹理,其中包含为当前帧计算的曝光值。此资源是可选的,如果 FFX_UPSCALE_ENABLE_AUTO_EXPOSURE 标志已在 flags 字段的 ffxCreateContextDescUpscale 结构中设置,则可以省略此资源。

所有在渲染分辨率下提供的输入(运动矢量除外)都应进行抖动渲染。除非存在 FFX_UPSCALE_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION 标志,否则不应对运动矢量应用抖动。

深度缓冲区配置

强烈建议使用反转的深度缓冲区与 FSR。但是,也支持其他深度缓冲区配置。应用程序应通过在创建 ffxCreateContextDescUpscale 时设置适当的标志来告知 FSR API 其深度缓冲区配置。下表包含适当的标志。

FSR 标志说明
FFX_UPSCALE_ENABLE_DEPTH_INVERTED一个位,指示提供的输入深度缓冲区数据是反转的 [max..0]。
FFX_UPSCALE_ENABLE_DEPTH_INFINITE一个位,指示提供的输入深度缓冲区数据使用的是无限远平面。

提供运动矢量

空间

时间算法(无论是抗锯齿还是放大)的一个关键部分是提供运动矢量。FSR 接受 2D 运动矢量,它编码了当前帧中像素到上一帧同一像素位置的运动。FSR 期望应用程序提供的运动矢量在 [<-width, -height>..<width, height>] 范围内;这与屏幕空间匹配。例如,屏幕左上角像素的运动矢量值为 <width, height>,表示一个横跨输入表面全部宽度和高度的运动,源自右下角。

alt text

如果你的应用程序在其他空间(例如归一化设备坐标空间)计算运动矢量,则可以使用 motionVectorScale 字段的 ffxDispatchDescUpscale 结构,指示 FSR 将其调整为匹配 FSR 的预期范围。下面的代码示例说明了如何将 NDC 空间运动矢量缩放到屏幕空间。下面的 HLSL 和 C++ 代码示例说明了如何使用 FSR 主机 API 来缩放 NDC 空间运动矢量。

// GPU: Example of application NDC motion vector computation
float2 motionVector = (previousPosition.xy / previousPosition.w) - (currentPosition.xy / currentPosition.w);
// CPU: Matching FSR motionVectorScale configuration
dispatchParameters.motionVectorScale.x = (float)renderWidth;
dispatchParameters.motionVectorScale.y = (float)renderHeight;

精度和分辨率

在许多情况下,FSR 内部使用 16 位量来表示运动矢量,这意味着虽然可以提供更高精度的运动矢量,但 FSR 目前将无法从中受益。运动矢量缓冲区的分辨率应等于渲染分辨率,除非在创建 flags 字段的 ffxCreateContextDescUpscale 结构(在创建 ffxContext 时)中设置了 FFX_UPSCALE_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS 标志,在这种情况下,它应等于呈现分辨率。

覆盖率

当提供更多对象的运动矢量时,FSR 将提供更好的质量放大。因此,建议所有不透明、Alpha 测试和 Alpha 混合对象都为所有覆盖的像素写入其运动矢量。如果应用了顶点着色器效果(例如滚动 UV),这些计算也应计入运动计算以获得最佳结果。

可选资源

FSR4 不再要求游戏生成“Reactive mask”或“Transparency and Composition mask”,尽管它们仍然可以提供给 FSR4。为了方便 FSR4 集成到也希望提供早期 FSR 版本的游戏(作为选项)中,已添加了一个新的 ffxQuery。通过使用 ffxQueryDescUpscaleGetResourceRequirements 作为查询结构,并将 FFX_API_QUERY_DESC_TYPE_UPSCALE_GET_RESOURCE_REQUIREMENTS 指定为查询标识符,调用者将收到一个位图,其中指定了 FfxApiQueryResourceIdentifiers 中定义的必需资源,以及一个用于可选资源的位图。这允许调用者确定何时执行生成蒙版的额外工作,何时可以省略它,从而降低 FSR4 的性能开销。使用有效的 context 调用 ffxQuery(用于此查询结构)将返回传入上下文版本的资源需求信息。要获取不同放大器版本或在放大器上下文创建之前的资源需求信息,请调用 ffxQuery(传入 NULL 上下文)并链接 ffxOverrideVersion。有关如何调用 Query 的代码示例,请参阅。

曝光

FSR 提供两个值来控制放大过程中使用的曝光。它们如下:

  1. 预曝光:一个值,我们将输入信号除以它,以恢复游戏在打包到低精度渲染目标之前生成的原始信号。
  2. 曝光:一个值,它乘以预曝光颜色值的计算结果。

曝光值应与应用程序在后续色调映射过程中使用的值匹配。这意味着 FSR 将与最终色调映射图像中可能看到的内容一致地运行。

在此文档中描述的 FSR 算法的各个阶段,FSR 将计算自己的曝光值供内部使用。值得注意的是,FSR 的所有输出将在写入最终输出之前,将其内部色调映射反转。这意味着 FSR 返回的结果与原始输入信号的域相同。

不当选择曝光值可能会对 FSR 放大效果的最终质量产生重大影响。因此,除非有特殊原因不这样做,否则建议应用程序使用 FFX_UPSCALE_ENABLE_AUTO_EXPOSURE。当 FFX_UPSCALE_ENABLE_AUTO_EXPOSURE 设置在 flags 字段的 ffxCreateContextDescUpscale 结构中时,使用下面 HLSL 代码所示的曝光计算来计算曝光值,该值与 ISO 100 胶片质量的曝光响应相匹配。

float ComputeAutoExposureFromAverageLog(float averageLogLuminance)
{
const float averageLuminance = exp(averageLogLuminance);
const float S = 100.0f; // ISO arithmetic speed
const float K = 12.5f;
const float exposureIso100 = log2((averageLuminance * S) / K);
const float q = 0.65f;
const float luminanceMax = (78.0f / (q * S)) * pow(2.0f, exposureIso100);
return 1 / luminanceMax;
}

在帧中的位置

FSR 的主要目标是通过使用依赖于多个输入的时域放大算法来提高应用程序的渲染性能。因此,其在管线中的位置是确保最高视觉质量与出色性能之间正确平衡的关键。

alt text

对于任何图像放大方法,了解如何将其他图像空间算法放置在放大算法之前是很重要的。将这些其他图像空间效果放在放大之前的好处是它们以较低的分辨率运行,这当然会为应用程序带来性能优势。然而,这可能不适用于某些类别的图像空间技术。例如,许多应用程序可能会在最终图像中引入噪点或颗粒,例如模拟物理相机。在放大器之前执行此操作可能会导致放大器放大噪点,从而在放大的图像中产生不希望出现的伪影。下表将常见的实时图像空间技术分为两列。“后期处理 A”包含所有通常应在 FSR 放大之前运行的技术,这意味着它们都将在渲染分辨率下运行。相反,“后期处理 B”列包含所有建议在 FSR 之后运行的技术,这意味着它们将在较大的呈现分辨率下运行。

后期处理 A后期处理 B
屏幕空间反射胶片颗粒
屏幕空间环境光遮蔽色差
去噪器(阴影、反射)晕影
曝光(可选)色调映射
光晕
景深
动态模糊

请注意,此处提出的建议仅供参考,具体取决于你的应用程序实现的具体特性。

时间抗锯齿

时间抗锯齿 (TAA) 是一种利用上一帧输出来构建当前帧更高质量输出的技术。由于 FSR 具有类似的目标(尽管还增加了提高渲染图像分辨率的目标),因此不再需要在应用程序中包含单独的 TAA 通道。

相机抖动

FSR 依赖应用程序在渲染时应用亚像素抖动 - 这通常包含在相机的投影矩阵中。为了简化相机抖动的应用,FSR API 提供了一小组实用函数,用于计算特定帧在独立抖动偏移序列中的亚像素抖动偏移。

内部,这些函数实现了 Halton[2,3] 序列 [Halton]。Halton 序列的目标是提供空间分离的点,这些点覆盖了可用空间。

alt text

重要的是要理解,从 ffxQueryDescUpscaleGetJitterOffset 返回的值以单位像素空间表示,为了将其正确地复合到投影矩阵中,我们必须将其转换为投影偏移。上面的图示显示了单位像素空间中的一个像素,以及在投影空间中的位置。下面的代码列表显示了如何将亚像素抖动偏移值正确地复合到投影矩阵中。

ffx::ReturnCode retCode;
int32_t jitterPhaseCount;
ffx::QueryDescUpscaleGetJitterPhaseCount getJitterPhaseDesc{};
getJitterPhaseDesc.displayWidth = displayWidth;
getJitterPhaseDesc.renderWidth = renderWidth;
getJitterPhaseDesc.pOutPhaseCount = &jitterPhaseCount;
retCode = ffx::Query(fsrContext, getJitterPhaseDesc);
ffx::QueryDescUpscaleGetJitterOffset getJitterOffsetDesc{};
getJitterOffsetDesc.index = jitterIndex;
getJitterOffsetDesc.phaseCount = jitterPhaseCount;
getJitterOffsetDesc.pOutX = &jitterX;
getJitterOffsetDesc.pOutY = &jitterY;
retCode = ffx::Query(fsrContext, getJitterOffsetDesc);
// Calculate the jittered projection matrix.
const float jitterX = 2.0f * jitterX / (float)renderWidth;
const float jitterY = -2.0f * jitterY / (float)renderHeight;
const Matrix4 jitterTranslationMatrix = translateMatrix(Matrix3::identity, Vector3(jitterX, jitterY, 0));
const Matrix4 jitteredProjectionMatrix = jitterTranslationMatrix * projectionMatrix;

抖动应应用于所有渲染。这包括不透明、Alpha 透明和光线追踪对象。对于光栅化对象,ffxQueryDescUpscaleGetJitterOffset 函数计算的亚像素抖动值可以应用于相机投影矩阵,该矩阵最终用于顶点着色过程中的变换。对于光线追踪渲染,亚像素抖动应应用于射线的起点 - 通常是相机的位置。

无论你是选择使用推荐的 ffxQueryDescUpscaleGetJitterOffset 查询还是自己的序列生成器,都必须设置 jitterOffset 字段的 ffxDispatchDescUpscale 结构,以告知 FSR 已应用的抖动偏移量以渲染每一帧。此外,如果未使用推荐的 ffxQueryDescUpscaleGetJitterOffset 查询,则应注意,你的抖动序列不得生成零向量;即 X 和 Y 维度均为 0。

下表显示了每个默认质量模式的抖动序列长度。

质量模式缩放因子序列长度
画质1.5x (每维)18
平衡1.7x (每维)23
性能2.0x (每维)32
超高性能3.0x (每维)72
自定义[1..n]x (每维)ceil(8 * n^2)

相机跳切

大多数具有实时渲染的应用程序在任何两个连续帧之间都具有高度的时间一致性。然而,在某些情况下,相机变换的变化可能导致渲染内容的突然变化。在这种情况下,FSR 不太可能重用它从前几帧累积的任何数据,因此应该清除这些数据,以排除其在复合过程中的考虑。为了指示 FSR 发生了相机跳切,你应该在不连续的相机变换的第一帧设置 reset 字段的 ffxDispatchDescUpscale 结构为 true

使用 reset 标志时,FSR 将清除一些额外的内部资源,因此渲染性能可能略低于典型的帧到帧操作。

Mipmap 偏差

应用负的 mipmap 偏差通常会生成具有更好纹理细节的放大图像。我们建议将以下公式应用于你的 Mipmap 偏差:

mipBias = log2(renderResolution/displayResolution) - 1.0;

建议应用程序为特定的高频纹理内容调整 MIP 偏差,这些内容容易出现时间混叠问题。

下表说明了根据上述伪代码计算出的、与应用程序应向最终用户提供的建议画质模式相匹配的缩放比例所产生的Mipmap偏置因子。

质量模式缩放因子Mipmap偏置
画质1.5倍 (每维度)-1.58
平衡1.7倍 (每维度)-1.76
性能2.0倍 (每维度)-2.0
超高性能3.0倍 (每维度)-2.58

帧时间增量输入

FSR API要求应用程序通过ffxDispatchDescUpscale结构体提供frameTimeDelta。此值以毫秒为单位:如果以60fps运行,则应传递约16.6f的值。

该值用于FSR自动曝光功能的时域组件中。

HDR 支持

FSR支持高动态范围图像。要启用此功能,您应该在ffxCreateContextDescUpscale结构的flags字段中设置FFX_UPSCALE_ENABLE_HIGH_DYNAMIC_RANGE位。为获得最佳效果,应以线性色彩空间向FSR提供图像。

非线性颜色

对于无法以线性色彩空间提供图像的应用程序,应在ffxCreateContextDescUpscale结构的flags字段中设置FFX_UPSCALE_ENABLE_NON_LINEAR_COLORSPACE标志。

此外,在FfxApiDispatchFsrUpscaleFlags中添加了两个可选标志,用于指定正在使用的特定色彩空间。

这些标志是互斥的,并在ffxDispatchDescUpscale结构体的flags字段中设置,然后告知FSR4输入图像使用的色彩空间。这可能在某些情况下比仅指定FFX_UPSCALE_ENABLE_NON_LINEAR_COLORSPACE能获得更好的视觉质量。

标志描述
FFX_UPSCALE_FLAG_NON_LINEAR_COLOR_SRGB表示输入颜色资源包含感知sRGB颜色。
FFX_UPSCALE_FLAG_NON_LINEAR_COLOR_PQ表示输入颜色资源包含感知PQ颜色。

未来版本的FSR可能会提供对其他色彩空间的支持。

调试器

启用调试检查器以在调度放大时验证应用程序提供的输入。此功能可以在运行时(例如,来自PrebuiltSignedDll文件夹的发布二进制文件或调试构建)的任何构建配置中启用。建议仅在游戏的开发构建中启用此功能。

ffxCreateContextDescUpscale的flags成员中传递FFX_UPSCALE_ENABLE_DEBUG_CHECKING标志,默认情况下会将放大器产生的文本警告消息输出到调试器的TTY。应用程序可以通过设置运行时回调函数将消息传递给底层应用程序。应用程序可以将ffxCreateContextDescUpscale中的fpMessage设置为合适的函数。fpMessage的类型为ffxApiMessage,它是一个函数指针,用于传递各种类型的字符串消息。

当检查器检测到潜在问题时可能发生的输出示例如下:

FSR_API_DEBUG_WARNING: FFX_FSR_ENABLE_DEPTH_INFINITE and FFX_FSR_ENABLE_DEPTH_INVERTED present, cameraFar value is very low which may result in depth separation artefacting
FSR_API_DEBUG_WARNING: frameTimeDelta is less than 1.0f - this value should be milliseconds (~16.6f for 60fps)

调试视图

当在ffxDispatchDescUpscale的flags属性中设置FFX_UPSCALE_FLAG_DRAW_DEBUG_VIEW时,将执行一个额外的调试输出通道,将内部表面的调试数据渲染到放大后的帧上。左上角显示的是运动向量,这可以用来确保您的动画对象能正确地向FSR报告运动。右上角可以检查FSR计算出的混合因子,明亮的紫色部分突出显示了与历史纹理低混合因子的区域,表明检测到了反应区域。

Frame interpolation debug overlay

构建示例

要构建FSR示例,请遵循以下说明:

  1. 下载并安装以下软件开发工具的最低版本:

  2. 打开Visual Studio解决方案

    终端窗口
    > <installation path>\Samples\FidelityFX_FSR\dx12\FidelityFX_FSR_2022.sln
  3. 首次vcpkg安装

  • 如果vcpkg尚未在Visual Studio中初始化,请执行以下操作:
    • 从菜单中选择工具,然后选择Visual Studio命令提示符以打开终端。
    • 键入vcpkg integrate install并按Enter键。
    • 关闭并重新打开解决方案。

构建项目

Visual Studio解决方案文件(.sln)将包含构建效果示例所需的所有项目。要构建解决方案中的项目,您应该从Visual Studio顶部的菜单中点击生成,然后点击生成解决方案。这将构建示例的所有依赖项(例如FidelityFX Cauldron Framework),然后构建示例应用程序。

运行项目

从Visual Studio运行项目

  1. 如果尚未突出显示,请在解决方案资源管理器中选择示例项目。

  2. 右键单击项目,然后选择设置为启动项目

  3. 右键单击项目,然后选择属性

  4. 配置属性下,单击调试条目。

  5. 为所有配置(DebugRelease)将工作目录设置为$(TargetDir)

  6. 单击应用,然后单击确定关闭属性面板。

  7. 从工具栏中单击生成菜单项,然后单击运行

局限性

FSR4需要AMD 9000系列GPU或更高版本。

版本历史

版本日期
4.0.2未发布

有关版本的更多详细信息,请参阅变更日志。

参考文献

[Halton] Halton序列,“Halton序列”https://en.wikipedia.org/wiki/Halton_sequence

另请参阅

© . This site is unofficial and not affiliated with AMD.