跳至内容

FidelityFX 可变着色 1.2

引言

在现代游戏中,渲染一帧的主要性能瓶颈之一是渲染每个像素所需的高计算能力,尤其是在高分辨率下。在高分辨率下渲染的一个副作用是,同一图元内相邻片段的世界空间位置通常非常接近,并且在同一图元内相邻像素着色器执行产生的颜色值通常会产生视觉上相似的结果。

几何边缘通常包含比图元内部更重要的视觉信息。多重采样抗锯齿 (MSAA) 利用这一点,通过保持较低的像素着色器执行次数,同时又计算最终帧所需的片段数。

FidelityFX 可变着色率 (VRS) 提供了一种类似的方式来减少像素着色器执行次数,并在它们由同一图元覆盖时,为多个相邻像素重用相同的输出值。这可以显著减少计算一帧所需的 ALU 和带宽,并在不损失视觉质量的情况下提高帧率。这意味着节省的 GPU 时间可以重新用于那些对最终帧有更大影响的效果,如果您在帧预算中有空间的话。

可以从一个角度来理解 VRS 的工作原理:想想 MSAA:如果一个 4K 帧以 2x2 VRS 进行渲染,那么所需的计算能力和最终图像质量将与以 4x MSAA 启用渲染的 1080p 图像相当。然而,VRS 提供了额外的功能,可以更精细地控制帧的哪些部分应该以较低分辨率渲染。

实现可变着色率

允许 VRS 的情况

存在多种情况,可以在不显著影响最终图像质量的情况下应用 VRS

  • 远处的物体通常更多地由其几何形状定义,而不是纹理细节(使用较低的 MIP 级别),并且远距离像素的颜色变化通常会因雾、大气效果或半透明几何体(例如粒子系统)而进一步减小。
  • 某些物体可能已知处于失焦状态,或已知会被后期处理效果(如运动模糊或辉光)模糊。
  • 某些物体可能因位于雾气或半透明物体(如水或磨砂玻璃)之后而变得扭曲或模糊。
  • 某些物体可能已知具有很少的细节变化(例如,为卡通渲染游戏渲染)或由于位于场景非常暗的部分(例如,在光线很少的场景中物体的未照明或阴影部分)。
  • 在快速移动的场景中,高帧率和低输入延迟很重要,但玩家不太可能注意到小的细节,因此积极使用 VRS 可以帮助实现性能目标。

除了上述情况之外,一些像素可能被认为对玩家来说不太重要,无论是通过眼动追踪(注视点渲染)还是其他系统,还是因为游戏设计旨在引导玩家的注意力到屏幕的某些部分。例如,游戏可以选择降低背景几何体的着色率,但确保所有敌人以最高质量渲染。

通过将 GPU 资源集中在使用最重要的地方来节省计算能力,VRS 可以用于确保达到目标帧时间(类似于动态分辨率缩放,但对细节需要保留的地方有更精细的控制),以及用于便携式设备的节能,而不会明显牺牲图像质量。

VRS 控制选项

DirectX12 中的 VRS 支持分为 2 个级别

  • 级别 1 允许为每个绘制调用设置着色率。这样,着色率就可以根据物体类型(重要性)、到摄像机的距离、移动速度或物体的屏幕空间位置进行调整。
  • 级别 2 增加了两种额外的技术,以更精细地控制着色率
    • SV_ShadingRate 可以从顶点或几何着色器导出,以控制每个图元的着色率。这样,例如,朝向主光源背面的图元、蒙皮网格的快速移动部分,或仅仅基于顶点属性中的艺术家规范,都可以被指示以较低的速率进行着色。
    • 可以绑定一个包含按屏幕瓦片基础使用哪个 VRS 倍率信息的 VRS 控制图像,以指定每个屏幕区域的 VRS 倍率。这可以用于独立于渲染物体的几何粒度来控制着色,基于屏幕区域、用户焦点区域,或通过分析前一帧的最终后备缓冲区来计算屏幕的哪些区域可能不会因降低着色率而受到很大影响。

所有三种模式可以同时使用:级别 2 定义了一个组合器树,该树决定了每个状态的结果如何与前一个状态的结果组合以计算最终的着色率。每个组合器的选项是:通过(传递前一个状态,即禁用当前阶段)、覆盖(忽略前一个阶段)、最小、最大和求和。

技术细节

VRS 的工作原理类似于 MSAA,像素着色器通常为每个像素执行一次,并将生成的值写入由图元覆盖的该像素的所有片段。VRS 为每个 VRS 粗像素执行一个像素着色器线程,一个粗像素可以包含 1、2 或 4 个像素(如果支持额外的着色率,则最多可以包含 16 个),然后将结果写入粗像素区域内由图元覆盖的所有像素。

这可以显著提高场景主要由使用昂贵像素着色器的大多边形组成的场景的性能。包含大量小型图元的绘制调用的性能从 VRS 中获益较少,但同时视觉质量也不会受到影响。此外,由于 VRS 不会减少写入渲染目标像素的数量,因此启用 VRS 不会降低填充率,因此不建议在填充率受限的通道中使用 VRS。

同样,由于深度和模板值通常在像素着色器执行之前计算和写入。在大多数情况下,仅深度通道没有像素着色器,或者至少没有昂贵的像素着色器,因此仅深度通道(例如阴影图渲染)不会从 VRS 中获益。

在处理深度值和 VRS 时,需要注意的是,像素着色器的样本位置可能与存储在深度缓冲区中的像素中心不同。在渲染读取深度缓冲区的几何体(如贴花或软粒子)时,必须考虑到从深度缓冲区读取的值与从顶点着色器传递过来的像素的深度值之间的差异,可能比未启用 VRS 时大得多。

最后,由于 VRS 瓦片的中心可能位于渲染几何体之外,因此在使用 VRS 时,应在像素着色器中启用质心插值,否则可能会导致伪影,例如采样纹理贴图的区域之外,该区域本应用于图元。使用质心插值将确保用于插值顶点属性的重心坐标始终位于图元覆盖的区域内。

如果像素着色器需要知道 VRS 瓦片的哪些像素被几何体覆盖的信息(例如,用于 alpha 测试几何体),可以通过读取 SV_Coverage 来评估。也可以从像素着色器导出覆盖掩码,但出于性能原因不推荐。

另请参阅

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