将 AMD FidelityFX™ 集成到 Ego Engine

首次发布:
最后更新:
Tom Hammersley's avatar
Tom Hammersley

AMD FidelityFX 对比度自适应锐化 (CAS) 是 AMD 新推出的开源库,它通过极低的集成成本即可同时提高图像质量和性能。

CAS 提供两项主要功能:

  • 对比度自适应锐化智能地增强图像质量和清晰度。
  • 高质量的缩放可以在保持画面清晰的同时提高渲染性能。

库结构

CAS 的设计旨在将源代码集成到您的引擎中。因此,代码可在 GitHub 上通过 MIT 开源许可证获取。核心 CAS 功能完全包含在一个 C++ 和 HLSL/GLSL 着色器专用的头文件库中。

集成 CAS 的过程并不比在引擎中实现新的全屏着色器通道复杂。您的引擎通过函数调用级别与 CAS 交互。CAS 不会直接与任何着色器资源绑定点交互,而这通常是集成中间件时的常见阻碍。

由于没有需要初始化的外部库或子系统,因此无需创建或管理额外的 GPU 资源,也无需进行 CPU 端内存分配。CAS 也不需要您为其准备诸如运动矢量之类的资源。任何转换处理都发生在着色器内部。

集成指南

CAS 最适合集成的具体点会因引擎而异。我建议在现代引擎的渲染管线中有一个通用点:在所有渲染和后期处理完成,处于线性空间后,应用 SDR/HDR 传输函数和 UI 渲染之前。这是 FidelityFX 的自然归宿,因为它在 **线性空间** 中运行并期望匹配的输入。

着色器结构

目前,CAS 需要一个计算着色器来促进一些优化。因此,我们将把线性输入纹理作为 SRV(着色器资源视图)进行读取,并写入 UAV(无序访问视图)。

此着色器需要几个简单的集成点:

  • 包含 CAS 头文件
  • 定义接口函数
  • 定义常量缓冲区
  • 计算着色器主体

头文件

CAS 头文件的设计旨在用于 C++ 或着色器代码。要在 HLSL 着色器中使用这些头文件,我们必须定义 `A_GPU` 和 `A_HLSL`。首先,我们 `#include "ffx_a.h"`,它在 CPU 和 GPU 之间提供了统一的类型和函数集。在定义了几个接口函数后,我们就可以包含主头文件 ffx_cas.h。

接口函数

由于 CAS 不会假设或要求我们如何访问或存储数据,因此我们必须提供函数供其访问我们的数据。这些函数是 `CasLoad()` 和 `CasInput()`。

`CasLoad()` 加载指定 xy 位置的纹理单元。由于我们提供代码,因此我们可以保证它与我们的着色器绑定方案相符。命名方案、寄存器绑定点或绑定无绑定方式之间不会发生冲突。

Texture2D srvInputTexture;
AF3 CasLoad( ASU2 p )
{
return srvInputTexture.Load( int3( p, 0 ) ).rgb;
}

`CasInput()` 提供了一个执行任何颜色空间转换到线性空间的选项。由于我假设我们的输入处于管线的线性空间部分,因此 `CasInput()` 只是一个空函数。

void CasInput( inout AF1 r, inout AF1 g, inout AF1 b ) {}

常量缓冲区

CAS 需要存储在 cbuffer 中的一些处理后的数据。由于 CAS 通过函数参数接受这些数据,因此我们可以将这些数据放置在单独的或合并的 cbuffer 中。数据只是 3 个 uint4。

cbuffer cb : register( b0 )
{
uint4 const0;
uint4 const1;
uint4 const2;
};

示例着色器主体

CAS 采用了与典型的 8x8 或 8x4 像素线程数安排略有不同的计算着色器结构。CAS 的模板着色器通过混淆计算着色器线程索引,以实现更有效的像素着色器寻址模式。这种结构在宽度和高度上都进行了 2 倍展开,进一步提高了效率。尽管进行了循环展开,但仍然创建了足够的线程来使现代 GPU 保持满负荷运行,即使在 1080p 分辨率下也是如此。

CAS 的主要工作函数是 `CasFilter()`。此函数的最后两个参数决定了缩放和质量。如果我们为第一个参数传递 true,则仅锐化图像,而不调整大小。如果我们为第二个参数传递 true,我们将运行一个成本稍低的算法版本。为了达到最高效率,我建议将不同的函数变体编译掉。

`CasFilter( …, true, false )` – 仅锐化 `CasFilter( …, false, false )` – 高质量缩放 `CasFilter( …, false, true )` – 低质量缩放

RWTexture2D uavOutputTexture;
[ numthreads( 64, 1, 1 ) ]
void cs_cas_sharpen_only( uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID )
{
AU2 gxy = ARmp8x8( LocalThreadId.x ) + AU2( WorkGroupId.x << 4u, WorkGroupId.y << 4u );
AF3 c;
CasFilter( c.r, c.g, c.b, gxy, const0, const1, true, false );
uavOutputTexture[ ASU2( gxy ) ] = AF4( c, 1 );
gxy.x += 8u;
CasFilter( c.r, c.g, c.b, gxy, const0, const1, true, false );
uavOutputTexture[ ASU2( gxy ) ] = AF4( c, 1 );
gxy.y += 8u;
CasFilter( c.r, c.g, c.b, gxy, const0, const1, true, false );
uavOutputTexture[ ASU2( gxy ) ] = AF4( c, 1 );
gxy.x -= 8u;
CasFilter( c.r, c.g, c.b, gxy, const0, const1, true, false );
uavOutputTexture[ ASU2( gxy ) ] = AF4( c, 1 );
}

尽管线程组维度不同寻常,但着色器仍然以 ((width + 15) / 16, (height + 15) / 16, 1) 进行调度。

CPU 端

显然,实现全屏着色器通道的细节大部分将取决于宿主引擎。CAS 在 CPU 端所需的唯一工作是填充 cbuffer。这就像调用 CAS 在 ffx_cas.h 中提供的函数一样简单。

#define A_CPU 1
#include "../../../../shaders_2019/cas/ffx_a.h"
#include "../../../../shaders_2019/cas/ffx_cas.h"
CasSetup( const0,
const1,
sharpness,
AF1( inputWidth ), AF1( inputHeight ),
AF1(outputWidth ), AF1(outputHeight) );

缩放

实现缩放所需的工作量很小。如前所述,着色器仅需要正确的函数参数。宿主引擎负责提供适当大小的输入和输出纹理。CAS 支持高达 4 倍的面积缩放,但显然限制缩放比例会带来更高的图像质量。`CasSupportScaling()` 可用于检查配置是否受支持。

性能和结果

CAS 非常高效。它的成本通常为零点几毫秒,这对于现代 GPU 上的全屏操作来说是典型的成本。此外,CAS 的设计自然适合集成到其他通道中,从而最大限度地降低成本。

CAS 为《F1 2019》带来了图像质量的明显提升,并且考虑到其集成所需时间有限,我们认为它为该游戏增添了非常有用的功能。从下载到原型中所有功能正常工作,仅用了两天的工作量。

我们没有观察到图像质量上有任何明显的缺点。我们无法检测到任何通常与锐化滤镜相关的伪影。

以下是一些示例。可以使用滑块观察差异。左侧是没有应用 CAS 的效果,右侧是应用了 CAS 的效果。

注意:您可能需要调整窗口大小才能正确查看这些 100% 的截图。

FidelityFX CAS Off
FidelityFX CAS On
PNG (960x640)
PNG (960x640)
FidelityFX CAS Off
FidelityFX CAS On
PNG (960x640)
PNG (960x640)
FidelityFX CAS Off
FidelityFX CAS On
PNG (960x640)
PNG (960x640)

结论

AMD FidelityFX CAS 以极低的性能成本提供了非常有用的图像质量提升。该套件设计精良,易于集成,且集成所需的时间和精力极少。最后,集成没有任何技术或法律障碍——AMD FidelityFX v1.1.4 可在所有类型的现代 GPU 上运行,并采用 MIT 开源许可证。

AMD FidelityFX 可在 https://github.com/GPUOpen-Effects/FidelityFX 获取。

更多信息

Tom Hammersley 的其他客座文章

Tom Hammersley's avatar

Tom Hammersley

Tom 是 Codemasters Software 的首席程序员,负责《F1》系列游戏。他在 PC 和所有游戏机平台上拥有超过 20 年的游戏行业经验。Tom 专注于所有平台、设备和 API 的渲染和优化。

相关新闻和技术文章

相关视频

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