- 图形学
- 游戏开发
【免费下载链接】dlssg-to-fsr3
Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).
FidelityFX Single Pass Downsampler(简称 FidelityFX SPD)是 AMD FidelityFX SDK 提供的一种高效降采样技术,能够在单次 Dispatch 调用内、借助 LDS(组共享内存)与可选的 Wave 操作,把一张输入纹理完整降采样生成到 1x1,覆盖全部 MIP 层级,而无需多个中间 Pass。本文以本仓库内 FidelityFX-SDK 依赖中的 single-pass-downsampler.md 技术文档为骨架,结合仓库内sdk/include/FidelityFX/gpu/spd/与sdk/include/FidelityFX/host/ffx_spd.h的源码实现、以及samples/spd/示例模块,完整讲解 SPD 的输入输出约定、算法结构、限制条件、集成参数(Flags、LDS、回调函数)与两种接入方式(静态库/原生集成),读完即可在自己的渲染管线中接入 SPD 并正确配置常量缓冲与全局原子计数器。
着色语言要求
FidelityFX SPD 的着色器同时支持HLSL与GLSL两种语言,Compute Shader 目标为CS_6_0(对应 Shader Model 6.0,依赖QuadReadAcrossX等 wave 内建函数,见 ffx_spd.h 中的SpdReduceQuad实现)。在 GLSL 侧则通过GL_KHR_shader_subgroup_quad扩展实现等价的 quad 归约。
技术原理:单 Pass 生成全部 MIP
SPD 的核心思路是:每个线程组(thread group)负责把输入纹理的一个 64x64 瓦片(tile)降采样到 1x1。算法流程如下:
- 每个 64x64 瓦片由一个
[numthreads(256,1,1)]的线程组独立处理,贡献 MIP 0 到 MIP 5(瓦片内部约 64x64 -> 1x1)。 - 线程组完成自己的瓦片后,通过全局原子计数器(global atomic counter)自增;随后读取计数器的返回值判断自己是否是"最后一个活跃线程组"。
- 若不是最后一个线程组,直接退出;若是最后一个线程组,则继续处理由所有线程组的 1x1 输出拼接而成的"最后一个瓦片",计算剩余的低分辨率 MIP 层级(MIP 6 及以下,最多到 MIP 11)。
这样一来,整个 4096x4096 纹理可以在一次 Dispatch 调用中直接降到 1x1,全程只有一次跨线程组同步,避免了传统多 Pass 方案每级 MIP 都要做一次全局同步的开销。
从源码看,SpdDownsample(位于 ffx_spd.h)的函数体正是这一流程的落实:先调用SpdDownsampleMips_0_1计算 MIP 0/1,再经SpdDownsampleNextFour计算 MIP 2~5;当mips > 6时通过SpdExitWorkgroup判断是否为最后一个线程组,是则SpdResetAtomicCounter复位计数器,接着由SpdDownsampleMips_6_7与下一轮SpdDownsampleNextFour(..., 8, ...)计算 MIP 6~11:
void SpdDownsample(FfxUInt32x2 workGroupID, FfxUInt32 localInvocationIndex, FfxUInt32 mips, FfxUInt32 numWorkGroups, FfxUInt32 slice) { // compute MIP level 0 and 1 SpdDownsampleMips_0_1(x, y, workGroupID, localInvocationIndex, mips, slice); // compute MIP level 2, 3, 4, 5 SpdDownsampleNextFour(x, y, workGroupID, localInvocationIndex, 2, mips, slice); if (mips <= 6) return; // increase the global atomic counter and check if it's the last remaining thread group if (SpdExitWorkgroup(numWorkGroups, localInvocationIndex, slice)) return; // reset the global atomic counter back to 0 for the next spd dispatch SpdResetAtomicCounter(slice); // compute MIP level 6 and 7 SpdDownsampleMips_6_7(x, y, mips, slice); // compute MIP level 8, 9, 10, 11 SpdDownsampleNextFour(x, y, FfxUInt32x2(0, 0), localInvocationIndex, 8, mips, slice); }输入约定
SPD 的输入由三部分组成,如下表所示(原文表格):
| 输入名 | 类型 | 说明 |
|---|---|---|
| 输入纹理(Input texture) | 2D Texture或2D Texture Array | 需要生成 MIP 层的资源,同时支持 2D 纹理与 2D 纹理数组。 |
| 常量(Constants) | Constant buffer | 一个常量缓冲,包含要生成的 MIP 层数,以及输入纹理中需要降采样的区域信息。 |
| 全局原子计数器(Global Atomic Counter) | [globallycoherent] RW buffer uint | 每个输入纹理 slice 一个全局原子计数器,初始化为 0。 |
输入纹理
输入纹理既可以是普通的 2D 纹理,也可以是以 2D 数组形式映射的 Cubemap。两种情况下都只需一次 Dispatch 即可生成全部 MIP 层。
在着色器中,输入纹理可以通过两种方式访问:
- 采样(sampler):当指定的内核函数计算的是 2x2 四边形平均值时,推荐直接使用线性采样器(linear sampler)完成平均,而不是手动计算;
- 直接读取(load):在无法使用线性采样器时,推荐使用 load 方式(load 优先于点采样 point sampling)。
输入纹理可以绑定为输出纹理数组的一部分(作为 UAV 访问),也可以单独绑定——既可以作为 UAV,也可以作为着色器资源视图(SRV)单独绑定。
常量缓冲(Constants)
- 如果使用静态库版本(host 层封装),常量会自动生成,此时 SPD 总是从零开始生成完整的 MIP 链;
- 如果已知纹理的某些区域与上一帧相比没有变化,可以只计算指定数量的 MIP 层,并且只降采样输入纹理的某个子区域(subregion),以节省开销。
ffxSpdSetup是一个 CPU 侧辅助函数,它根据传入的子区域(left、top、width、height)与 MIP 层数(传 -1 表示 MAX)自动填充常量缓冲。常量缓冲必须定义以下三个参数:
mips:要计算的 MIP 层数。传 -1 时由ffxSpdSetup依据子区域的宽高计算最大 MIP 层数。从 ffx_spd.h 的源码看,其上限被限制为 12 层:numWorkGroupsAndMips[1] = min(floor(log2(resolution)), 12);numWorkGroups:每个 slice 分发的线程组数量。每个线程组负责降采样一个 64x64 瓦片,ffxSpdSetup根据子区域计算出线程组数量:numWorkGroups = dispatchX * dispatchY;workGroupOffset:线程组偏移量,用于让线程组只处理指定子区域内的瓦片。源码中由rectInfo[0]/64与rectInfo[1]/64(left、top 分别除以 64)计算得出,dispatch 数量则由(endIndexX + 1 - offsetX) * (endIndexY + 1 - offsetY)得出,其中endIndexX = (left + width - 1) / 64。
全局原子计数器
- SPD 期望每个 slice 一个全局原子计数器(uint),并且必须初始化为 0;
- SPD 会在一次 Dispatch 结束时把计数器自动复位为 0,以便下一次 Dispatch 直接使用;
- 如果计数器的内存存在别名(aliasing)情况,应用有责任保证 Dispatch 开始时计数器为 0;
- 着色器中计数器必须带
[globallycoherent]标签,因为它的值需要对所有线程组可见。
输出约定
SPD 的输出如下表所示(原文表格):
| 输出名 | 类型 | 说明 |
|---|---|---|
| 输出纹理(Output texture) | Array of 2D Textures 或 2D Texture Array | 输入纹理计算得到的 MIP 层。 |
| 输出纹理 MIP 第 6 层 | [globallycoherent] 2D Texture或[globallycoherent] 2D Texture Array | 以 globally coherent 标签绑定的第 6 级 MIP。 |
输出纹理
输出纹理是一个 2D 纹理数组;当 SPD 降采样的是 Cubemap 时,则是 2D 纹理数组的数组(即每个 cube face 一组数组)。
每个 slice 的MIP 6 会被绑定两次——一次作为纹理数组的一部分,另一次以[globallycoherent]标签单独绑定。着色器本身只访问单独绑定的 MIP 6 资源。之所以需要[globallycoherent]标签,是因为 MIP 6 的内容需要被所有线程组可见(它是由所有线程组的 1x1 结果组成的)。这一设计在 ffx_spd_callbacks_hlsl.h 中对应rw_input_downsample_src_mid_mip(globallycoherent UAV)与rw_input_downsample_src_mips[SPD_MAX_MIP_LEVELS+1]两组资源声明。
算法结构
- SPD 为输入纹理的每个 64x64 瓦片派生一个线程组,每个瓦片独立降采样到 1x1,贡献 MIP 1~6 层;MIP 6 的每个像素由不同的线程组计算得出;
- 剩余的 MIP 层由最后一个活跃线程组计算;
- 每个线程组完成自己的瓦片降采样后,递增一个全局计数器并检查该计数器的值是否等于瓦片总数:
- 若不等,则线程组终止;
- 若相等,则说明自己是最后一个活跃线程组,继续完成剩余降采样。
- 这种方式保证了 SPD 中只有一次跨线程组同步,而不是每个 MIP 层之后各同步一次;其余所有同步都发生在单个线程组内部——线程组内通过LDS(组共享内存)和可选的Wave 操作共享数据。
从 ffx_spd.h 的SpdExitWorkgroup可以看到这一"最后一个线程组"判定逻辑:只有localInvocationIndex == 0的线程执行SpdIncreaseAtomicCounter原子自增,随后通过组内存屏障ffxSpdWorkgroupShuffleBarrier让所有线程可见返回值,再与numWorkGroups - 1比较:
bool SpdExitWorkgroup(FfxUInt32 numWorkGroups, FfxUInt32 localInvocationIndex, FfxUInt32 slice) { // global atomic counter if (localInvocationIndex == 0) { SpdIncreaseAtomicCounter(slice); } ffxSpdWorkgroupShuffleBarrier(); return (SpdGetAtomicCounter() != (numWorkGroups - 1)); }限制条件
- SPD 目前只支持2x2 内核,以及每个 MIP 层的min、max 或 mean(平均)运算;
- 在奇数尺寸的情况下,最后一行或最后一列会被忽略。例如 7x4 的分辨率会产生 3x2 的 MIP 层,其数值来自 6x4 子区域,第 7 行被忽略;
- 解决办法:
- 将输入纹理填充到 2 的幂的尺寸;
- 或将输入纹理填充到 64 的倍数,然后针对由最后一个剩余线程组计算的 MIP 层(这些 MIP 全部在全局计数器判定之后计算)手动处理奇数分辨率的情况。
集成指南
用户在集成时有一些选项可以设置,这些选项会影响性能。
Flags(FfxSpdInitializationFlagBits)
在 host 层通过FfxSpdInitializationFlagBits位标志配置,在原生集成时则通过着色器代码中的宏定义配置。从 host/ffx_spd.h 的枚举定义,各标志位及含义如下:
| 标志位 | 值 | 含义 |
|---|---|---|
FFX_SPD_SAMPLER_LOAD | 1 << 0 | 使用资源 load 读取输入(优先 load 而非采样) |
FFX_SPD_SAMPLER_LINEAR | 1 << 1 | 使用 sampler 加载资源(线性采样) |
FFX_SPD_WAVE_INTEROP_LDS | 1 << 2 | 使用 LDS 进行线程间数据共享 |
FFX_SPD_WAVE_INTEROP_WAVE_OPS | 1 << 3 | 使用 Wave 操作(优先 Wave Ops 而非 LDS) |
FFX_SPD_MATH_NONPACKED | 1 << 4 | 使用 32 位浮点运算 |
FFX_SPD_MATH_PACKED | 1 << 5 | 使用 16 位半精度浮点运算(更受推荐) |
Wave 操作(Wave operations)
默认情况下 SPD 会同时使用 Wave 操作与组共享内存(LDS)在单一线程组内共享数据。如果不支持 Wave 操作,设置FFX_SPD_OPTION_WAVE_INTEROP_LDS标志,让 SPD 只使用 LDS。该宏会影响性能。
Half 类型(Half types)
SPD 支持 half(16 位)类型。如果 16 位精度足够,推荐设置FFX_SPD_MATH_PACKED标志。在着色器侧,packed 版本由FFX_HALF宏切换,并调用SpdDownsampleH以及一组带H后缀的回调(SpdLoadSourceImageH、SpdLoadH、SpdStoreH、SpdReduce4H等)。GLSL 下还会额外 requireGL_EXT_shader_subgroup_extended_types_float16扩展(见 ffx_spd.h)。
采样器(Sampler)
SPD 支持通过线性采样器或纹理 load 访问输入纹理。推荐使用 load,除非你能使用线性采样器;设置FFX_SPD_SAMPLER_LINEAR标志来采样输入纹理。在着色器中线性采样模式通过SPD_LINEAR_SAMPLER宏控制——当该宏定义时SpdReduceLoadSourceImage直接调用SpdLoadSourceImage(base)(一次线性采样即完成 2x2 平均),否则手动加载 4 个 texel 再归约(见 ffx_spd.h)。
组共享内存(LDS)
SPD 使用组共享内存在单一线程组内共享数据,所需的内存量取决于是否使用 half 类型。可以用 float4 定义:
float4 spdIntermediate[16][16];或者用 float 分别定义:
float spdIntermediateR[16][16]; float spdIntermediateG[16][16]; float spdIntermediateB[16][16]; float spdIntermediateA[16][16];对于 half 类型使用:
min16float4 spdIntermediate[16][16];或:
min16float2 spdIntermediateRG[16][16]; min16float2 spdIntermediateBA[16][16];此外还需要在组共享内存中定义一个计数器。该计数器用于保存原子加操作的返回值,以便每个线程判断自己是终止还是继续。结合SpdExitWorkgroup的源码可以看到:只有线程 0 调用原子加,返回值存入共享内存,组内所有线程再通过屏障读取,据此决定退出或继续。
回调函数
FidelityFX SPD 要求用户定义以下回调函数(如需支持 half 类型,则使用带H后缀的版本):
| 回调函数 | 职责 |
|---|---|
SpdLoadSourceImage[H] | 对给定 UV 和 slice,从输入纹理采样或加载数据。 |
SpdLoad[H] | 从单独绑定的、带[globallycoherent]标签的 MIP 6 资源加载数据;仅由最后一个活跃线程组使用。 |
SpdStore[H] | 将输出存储到 MIP 层;若 mip 值为 5(对应 64x64 瓦片归约到 2x2 的结果,即最后一块的输入),则结果需存储到带[globallycoherent]标签的单独绑定 MIP 6 资源。 |
SpdIncreaseAtomicCounter | 递增全局原子计数器;每个 slice 一个计数器。原子加返回上一个值,该值需存入共享内存——因为只有线程 0 调用原子加,这样线程组内所有线程都能访问该值,用于判断终止或继续。 |
SpdGetAtomicCounter | 读取保存在共享内存中的全局原子计数器值。 |
SpdResetAtomicCounter | 将指定 slice 的全局原子计数器复位为 0。 |
SpdReduce4[H] | 用户指定的 2x2 -> 1 归约内核;常见的归约函数为 min、max 或平均值。 |
SpdLoadIntermediate[H] | 从组共享缓冲区加载数据。 |
SpdStoreIntermediate[H] | 向组共享缓冲区存储数据。 |
在官方 HLSL 回调模板 ffx_spd_callbacks_hlsl.h 中,这些回调分别映射到SampleSrcImage/LoadSrcImage/StoreSrcMip(输入源)、LoadMidMip/StoreMidMip(MIP 6 的 globallycoherent UAV)以及IncreaseAtomicCounter(基于InterlockedAdd实现)等内置实现;原生集成时可按需自行改写。
主函数(Main function)
在着色器入口中调用SpdDownsample[H],线程组尺寸固定为[numthreads(256,1,1)]。示例 CSMain:
[numthreads(256, 1, 1)] void main( uint3 WorkGroupId : SV_GroupID , uint LocalThreadId : SV_GroupIndex ) { #if FFX_HALF SpdDownsampleH(WorkGroupId.xy, LocalThreadId, Mips(), NumWorkGroups(), WorkGroupId.z, WorkGroupOffset()); #else SpdDownsample(WorkGroupId.xy, LocalThreadId, Mips(), NumWorkGroups(), WorkGroupId.z, WorkGroupOffset()); #endif // FFX_HALF }其中Mips()、NumWorkGroups()、WorkGroupOffset()是从常量缓冲cbSPD读取的辅助函数(定义于 ffx_spd_callbacks_hlsl.h),对应字段mips、numWorkGroups、workGroupOffset(以及线性采样模式专用的invInputSize)。
示例 C++ 代码
方式一:静态库(host 层)集成——使用ffxSpdContextCreate创建上下文、ffxSpdContextDispatch派发:
FfxSpdDispatchDescription dispatchParameters = {}; dispatchParameters.commandList = ffxGetCommandList(pCmdList); dispatchParameters.resource = ffxGetResource(m_pCubeTexture->GetResource(), L"SPD_Downsample_Resource", FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); FfxErrorCode errorCode = ffxSpdContextDispatch(&m_SPDContext, &dispatchParameters); FFX_ASSERT(errorCode == FFX_OK);静态库版本对应的 host 接口完整生命周期为:ffxSpdContextCreate->ffxSpdContextDispatch->ffxSpdContextDestroy,上下文大小由FFX_SPD_CONTEXT_SIZE (9300)个 32 位值定义,配置结构FfxSpdContextDescription由flags、downsampleFilter(FFX_SPD_DOWNSAMPLE_FILTER_MEAN/MIN/MAX)与backendInterface三部分组成(见 host/ffx_spd.h)。
方式二:原生集成(low level)——手动调用ffxSpdSetup填充常量缓冲,然后自行 Dispatch:
ffxSpdSetup(dispatchThreadGroupCountXY, workGroupOffset, numWorkGroupsAndMips, rectInfo); // downsample uint32_t dispatchX = dispatchThreadGroupCountXY[0]; uint32_t dispatchY = dispatchThreadGroupCountXY[1]; uint32_t dispatchZ = m_cubeTexture.GetArraySize(); SpdConstants constants; constants.numWorkGroupsPerSlice = numWorkGroupsAndMips[0]; constants.mips = numWorkGroupsAndMips[1]; constants.workGroupOffset[0] = workGroupOffset[0]; constants.workGroupOffset[1] = workGroupOffset[1]; ... // Dispatch pCommandList->Dispatch(dispatchX, dispatchY, dispatchZ);这里ffxSpdSetup是 CPU 侧函数(FFX_CPU分支编译进 ffx_spd.h),其核心计算逻辑为:workGroupOffset = (left/64, top/64)、dispatchThreadGroupCountXY = (endIndexX+1-offsetX, endIndexY+1-offsetY)、numWorkGroupsAndMips[0] = dispatchX*dispatchY、numWorkGroupsAndMips[1] = mips(mips 为 -1 时按min(floor(log2(max(width,height))), 12)计算)。着色器侧的对应入口则是SpdDownsample(workGroupID, localInvocationIndex, mips, numWorkGroups, slice, workGroupOffset),它会将workGroupID + workGroupOffset后调用无偏移版本。
库与着色器代码的组织方式
ffx_spd.h头文件设计为同时可被 C++ 与 HLSL/GLSL 通过#define宏包含,具体见示例文档 single-pass-downsampler.md:
C++ 侧:
#define FFX_CPU #include <gpu/ffx_core.h> #include <gpu/ffx_spd.h>HLSL 侧:
#define FFX_GPU #define FFX_HLSL #include "ffx_core.h" #include "ffx_spd.h"GLSL 侧:
#define FFX_GPU #define FFX_GLSL #include "ffx_core.h" #include "ffx_spd.h"注意:ffx_spd.h依赖ffx_core.h,因此两者必须一起包含。
SPD 的 GPU 侧代码由仓库中sdk/include/FidelityFX/gpu/spd/目录下的若干头文件构成:
- ffx_spd.h:核心算法(
SpdDownsample、各 MIP 归约函数、ffxSpdSetupCPU 辅助函数); - ffx_spd_downsample.h:降采样主流程拆分;
- ffx_spd_callbacks_hlsl.h / ffx_spd_callbacks_glsl.h:HLSL/GLSL 的默认回调实现与资源声明;
- ffx_spd_resources.h:资源标识符枚举(
FFX_SPD_RESOURCE_IDENTIFIER_*,共 17 个,含INPUT_DOWNSAMPLE_SRC、INPUT_DOWNSAMPLE_SRC_MID_MIPMAP、INTERNAL_GLOBAL_ATOMIC等)与SPD_MAX_MIP_LEVELS 12常量。
示例模块与 UI 配置
仓库中的 SPD 示例位于 samples/spd/,包含渲染模块 spdrendermodule.cpp、着色器 spd_cs_downsampler.hlsl(多 Pass CS 对比实现)、spd_ps_downsampler.hlsl(多 Pass PS 对比实现)、spd_verify_results.hlsl(结果验证)以及模块配置 spdconfig.json(渲染管线顺序为 GBuffer -> SkyDome -> SPDRenderModule -> ToneMapping)。
示例的运行环境要求为 Windows + DirectX 12 或 Vulkan。示例 UI 提供了四个与 SPD 直接相关的开关(见示例文档 single-pass-downsampler.md 的 UI 元素表):
| 元素名 | 可选值 | 作用 |
|---|---|---|
| Downsampler Option | SPD CS, Multipass CS, Multipass PS | 在 FidelityFX 单 Pass 降采样计算着色器(SPD CS)、多 Pass 计算着色器(Multipass CS)与多 Pass 像素着色器(Multipass PS)之间切换对比。 |
| SPD Load/Linear | Load, Linear | 切换采样方式:线性插值采样或像素 load;用于 SPD 计算着色器采集输入颜色。 |
| SPD Wave Interop | WaveOps, LocalDataShare | 切换线程间互操作方式:wave 内建操作(如WaveReadLaneAt)或本地数据共享(LDS)+ 原子操作;WaveOps通常更快。 |
| SPD Math | Packed, Non-Packed | 切换 packed 16 位浮点运算与非 packed 32 位浮点运算。 |
在 spdrendermodule.cpp 的UpdateSPDContext中,UI 选项被映射为初始化标志位:m_SPDLoadLinear ? FFX_SPD_SAMPLER_LINEAR : FFX_SPD_SAMPLER_LOAD、m_SPDWaveInterop ? FFX_SPD_WAVE_INTEROP_WAVE_OPS : FFX_SPD_WAVE_INTEROP_LDS、m_SPDMath ? FFX_SPD_MATH_PACKED : FFX_SPD_MATH_NONPACKED,随后调用ffxSpdContextCreate;每次选项变化或窗口尺寸变化(OnResize)时都会销毁并重建上下文。
该示例共演示8 种 SPD 计算着色器排列组合(FP16/FP32 × wave-ops/LDS × load/linear-sampler),运行时根据硬件能力与 UI 配置选择具体组合:
- FP16-wave-ops-load(
A_HALF=1+spd_integration.hlsl) - FP16-no-wave-ops-load(
A_HALF=1、SPD_NO_WAVE_OPERATIONS=1+spd_integration.hlsl) - FP16-wave-ops-linear-sampler(
A_HALF=1+spd_integration_linear_sampler.hlsl) - FP16-no-wave-ops-linear-sampler(
A_HALF=1、SPD_NO_WAVE_OPERATIONS=1+spd_integration_linear_sampler.hlsl) - FP32-wave-ops-load(仅
spd_integration.hlsl) - FP32-no-wave-ops-load(
SPD_NO_WAVE_OPERATION=1+spd_integration.hlsl) - FP32-wave-ops-linear-sampler(仅
spd_integration_linear_sampler.hlsl) - FP32-no-wave-ops-linear-sampler(
SPD_NO_WAVE_OPERATION=1+spd_integration_linear_sampler.hlsl)
SPD 的两种使用层级
SPD 支持两种集成方式(详见示例文档):
- 低层使用(Low level):直接包含
gpu/spd/ffx_spd.h的着色器代码,手动设置输入(常量缓冲、全局原子计数器、LDS、回调函数),调用侧代码拥有最大的灵活性; - 高层使用(High level):使用
host/ffx_spd.h中的效果组件,通过简单的ffxSpdContextDispatch调用,按传入选项自动完成整张纹理的降采样。
静态库版本在使用时自动生成常量并始终从零生成完整 MIP 链;而原生集成版本则可利用ffxSpdSetup+ 子区域参数实现部分 MIP 计算与局部区域降采样,适合纹理内容逐帧部分更新的场景(例如仅更新了动态光源影响的区域时,只降采样该子区域即可复用上一帧其余区域的低分辨率结果)。
相关资源
- FidelityFX Single Pass Downsampler 示例文档
- FidelityFX 命名规范(Naming guidelines)
- 运行示例(Running the samples)
- GPU 核心实现:ffx_spd.h、ffx_spd_downsample.h、ffx_spd_callbacks_hlsl.h、ffx_spd_resources.h
- Host 层接口:host/ffx_spd.h
- 示例模块:samples/spd/spdrendermodule.cpp 与 samples/spd/config/spdconfig.json
- 图形学
- 游戏开发
【免费下载链接】dlssg-to-fsr3
Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).
相关推荐
dlssg-to-fsr3技术深度:从底层算法到上层应用的完整技术栈
dlssg to fsr3技术深度:从底层算法到上层应用的完整技术栈 dlssg to fsr3 是一个革命性的开源项目,它通过替换Nvidia DLSS G帧
图形学游戏开发Lightweight Charts™ 时区处理完全指南:UTC 时间戳偏移、三种转换方案与性能取舍
Lightweight Charts™ 时区处理完全指南:UTC 时间戳偏移、三种转换方案与性能取舍 导读 Lightweight Charts™ 是一款基于
图形学游戏开发dlssg-to-fsr3技术原理图解:从光流计算到帧插值的完整流程
dlssg to fsr3技术原理图解:从光流计算到帧插值的完整流程 AMD FidelityFX Super Resolution 3 FSR3 帧生成技术通
图形学游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考