FidelityFX Blur 1.1 技术详解:Compute Shader 单趟高斯模糊的集成与实现原理(dlssg-to-fsr3 仓库 FidelityFX SDK 依赖篇)

📅 发布时间:2026/10/4 13:52:35
FidelityFX Blur 1.1 技术详解:Compute Shader 单趟高斯模糊的集成与实现原理(dlssg-to-fsr3 仓库 FidelityFX SDK 依赖篇)
图形学游戏开发【免费下载链接】dlssg-to-fsr3Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).项目地址https://gitcode.com/gh_mirrors/dl/dlssg-to-fsr3点击查看免费下载FidelityFX Blur 1.1 是 AMD FidelityFX SDK 中一款基于 Compute Shader 的高性能单趟single-pass高斯模糊技术通过线程组共享内存LDS缓存中间结果将传统两趟可分离高斯模糊合并为一次 compute dispatch 完成。本文以 dependencies/FidelityFX-SDK/docs/techniques/blur.md 为主干结合当前仓库gh_mirrors/dl/dlssg-to-fsr3即 dlssg-to-fsr3 项目中内嵌的 FidelityFX SDK 依赖中的宿主 API 头文件与 GPU 着色器源码系统讲解 FfxBlur 的完整集成流程、可自定义回调机制、内核权重/内核尺寸/浮点精度等核心参数以及水平模糊缓存 垂直模糊输出三步算法与环形缓冲区共享内存布局。读完本文你将能够直接把 FidelityFX Blur 集成进自己的渲染管线或基于自定义 main 函数与回调重写属于自己的模糊计算内核。一、技术概览与环境要求FidelityFX Blur 是一款compute-based、高度优化、单趟完成的高斯模糊技术。它在上层 API 层面表现为一个独立的 FfxBlurContext功能上与标准两趟可分离高斯模糊完全等价但性能更高——这正是它与其他常规模糊实现的核心差异。项目要求HLSLCS_6_0Compute Shader 6.0GLSLversion 450版本号FFX_BLUR_VERSION_MAJOR 1/MINOR 1/PATCH 0见 ffx_blur.h内部上下文数量FFX_BLUR_CONTEXT_COUNT 1宿主头文件 ffx_blur.h 将其描述为在 compute shader 上实现、针对极致性能手工优化的模糊效果集合当前包含一种效果支持最大 21x21 内核的高斯模糊。GPU 侧入口函数为ffxBlurPass封装于 ffx_blur_blur.h实际算法主体为ffxBlur定义于 ffx_blur.h。二、C SDK 集成指南宿主侧 API使用 FFX SDK C API 集成 Blur 是最简单的方式整体流程分为三步初始化上下文 → 逐帧执行 Dispatch → 销毁上下文。2.1 初始化 FfxBlurContext// Initialize the FFX backend and blur context (do this once) size_t scratchBufferSize ffxGetScratchMemorySize(FFX_BLUR_CONTEXT_COUNT); void* scratchBuffer malloc(scratchBufferSize); FfxInterface backendInterface; ffxGetInterface(backendInterface, GetDevice(), scratchBuffer, scratchBufferSize, FFX_BLUR_CONTEXT_COUNT); FfxBlurContextDescription desc {}; desc.backendInterface backendInterface; desc.floatPrecision FFX_BLUR_FLOAT_PRECISION_32BIT; desc.kernelPermutations FFX_BLUR_KERNEL_PERMUTATIONS_ALL; // mask to support some Guassian sigma kernels or ALL desc.kernelSizes FFX_BLUR_KERNEL_SIZE_ALL; // mask to support some kernel sizes or ALL FfxBlurContext blurContext; ffxBlurContextCreate(blurContext, desc);关键点说明scratch 缓冲ffxGetScratchMemorySize(FFX_BLUR_CONTEXT_COUNT)返回后端所需 scratch 内存大小FFX_BLUR_CONTEXT_COUNT为 1Blur 仅需一个内部效果上下文。backendInterface通过ffxGetInterface绑定当前设备的后端实现DX12 / Vulkan。创建/销毁ffxBlurContextCreate与ffxBlurContextDestroy是上下文生命周期管理的唯二入口声明见 ffx_blur.h。2.2 FfxBlurContextDescription 核心参数依据 ffx_blur.h上下文描述结构体包含四个字段字段类型含义kernelPermutations位掩码使能的 Gaussian sigma 内核排列1.6 / 2.8 / 4.0kernelSizes位掩码使能的内核尺寸3x3 … 21x21floatPrecision枚举期望的浮点精度FP32 / FP16backendInterface结构体指向 FFX 后端实现的一组函数指针其中FFX_BLUR_KERNEL_PERMUTATIONS_ALL与FFX_BLUR_KERNEL_SIZE_ALL是全部使能的便捷宏前者为(1 FFX_BLUR_KERNEL_PERMUTATION_COUNT) - 13 种 sigma 全开后者为(1 FFX_BLUR_KERNEL_SIZE_COUNT) - 110 种内核尺寸全开。2.3 逐帧执行ffxBlurContextDispatch// Execute blur effect (multiple times) FfxBlurDispatchDescription desc {}; desc.commandList ffxGetCommandList(pCmdList); desc.kernelPermutation FFX_BLUR_KERNEL_PERMUTATION_2; // Guassian sigma (1.6, 2.8, or 4.0) desc.kernelSize FFX_BLUR_KERNEL_SIZE_15x15; // Kernel sizes (3x3 ... 21x21) desc.input ffxGetResource(inputResource, LBLUR_InputSrc, FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); desc.inputAndOutputSize.width desc.input.description.width; desc.inputAndOutputSize.height desc.input.description.height; desc.output ffxGetResource(outputResource, LBLUR_Output, FFX_RESOURCE_STATE_UNORDERED_ACCESS); ffxBlurContextDispatch(blurContext, desc); // When done using the blur effect, clean up. ffxBlurContextDestroy(blurContext);FfxBlurDispatchDescription的完整字段见 ffx_blur.h字段说明commandList用于记录渲染命令的FfxCommandListkernelPermutation本次使用的 sigma 排列必须是 Context 创建时使能的排列之一kernelSize本次使用的内核尺寸必须是 Context 创建时使能的尺寸之一inputAndOutputSize输入输出资源的宽高像素input待模糊的输入资源状态为FFX_RESOURCE_STATE_PIXEL_COMPUTE_READoutput模糊结果输出资源状态为FFX_RESOURCE_STATE_UNORDERED_ACCESS2.4 参数取值范围速查枚举定义以下枚举均定义于 ffx_blur.h内核排列sigma 值——FfxBlurKernelPermutation枚举值位含义FFX_BLUR_KERNEL_PERMUTATION_010sigma 1.6FFX_BLUR_KERNEL_PERMUTATION_111sigma 2.8FFX_BLUR_KERNEL_PERMUTATION_212sigma 4.0内核尺寸——FfxBlurKernelSize全部为奇数内核从 3x3 到 21x21共 10 档枚举值位枚举值位FFX_BLUR_KERNEL_SIZE_3x310FFX_BLUR_KERNEL_SIZE_13x1315FFX_BLUR_KERNEL_SIZE_5x511FFX_BLUR_KERNEL_SIZE_15x1516FFX_BLUR_KERNEL_SIZE_7x712FFX_BLUR_KERNEL_SIZE_17x1717FFX_BLUR_KERNEL_SIZE_9x913FFX_BLUR_KERNEL_SIZE_19x1918FFX_BLUR_KERNEL_SIZE_11x1114FFX_BLUR_KERNEL_SIZE_21x2119浮点精度——FfxBlurFloatPrecisionFFX_BLUR_FLOAT_PRECISION_32BIT 0、FFX_BLUR_FLOAT_PRECISION_16BIT 1。FP16 变体会在 ffx_blur_callbacks_hlsl.h 中通过FFX_HALF宏选择FfxFloat16类型的 I/O 与内核权重。三、通过回调与自定义 main 函数定制 BlurBlur 在 ffx_blur_callbacks_hlsl.h 与 ffx_blur_callbacks_glsl.h 中提供了默认的内核权重与 I/O 函数实现SDK 使用者可以将其替换以对接自己的应用资源绑定。3.1 内核权重回调的重写规则Blur 要求1D 内核权重在编译时嵌入着色器以获得最大性能具体要求如下函数签名中的权重类型为FfxFloat32或FfxFloat16由是否启用半精度决定这两个类型定义于 ffx_core.h必须提供一组归一化的高斯权重分布以静态数组形式定义元素按递减顺序排列从中心权重到边缘权重。官方示例5x5 高斯内核覆盖#if FFX_HALF #define FFX_BLUR_KERNEL_TYPE FfxFloat16 #else #define FFX_BLUR_KERNEL_TYPE FfxFloat32 #endif inline FFX_BLUR_KERNEL_TYPE GetKernelWeight(int iKernelIndex) { static FFX_BLUR_KERNEL_TYPE kernel_weights[] { 0.257030201088974, 0.22378581991669, 0.147699079538823 }; // for a 5x5 Gaussian kernel return kernel_weights[iKernelIndex]; } FFX_BLUR_KERNEL_TYPE FfxBlurLoadKernelWeight(FfxInt32 iKernelIndex) { return GetKernelWeight(iKernelIndex); }从源码层面印证默认实现 ffx_blur_callbacks_hlsl.h 内嵌了 3 种 sigma1.6 / 2.8 / 4.0x 10 种尺寸FFX_BLUR_KERNEL_RANGE从 2 到 11的完整权重表并通过FFX_BLUR_OPTION_KERNEL_PERMUTATION0/1/2与FFX_BLUR_OPTION_KERNEL_DIMENSION两个宏在编译期选取具体数组FFX_BLUR_KERNEL_RANGE ((FFX_BLUR_OPTION_KERNEL_DIMENSION - 1) / 2) 1即中心 半宽。若未定义FFX_BLUR_OPTION_KERNEL_DIMENSION编译会直接报错见 ffx_blur.h这正是权重必须编译期确定的设计体现。3.2 I/O 回调的重写示例#if FFX_HALF FfxFloat16x3 FfxBlurLoadInput(FfxInt16x2 inPxCoord) { return texColorInput[inPxCoord].rgb; } void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat16x3 color) { texColorOutput[outPxCoord] min16float4(color, 1); } #else FfxFloat32x3 FfxBlurLoadInput(FfxInt32x2 inPxCoord) { return texColorInput[inPxCoord].rgb; } void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color) { texColorOutput[outPxCoord] float4(color, 1); } #endif注意默认实现的资源绑定约定输入纹理为r_input_srcSRVFFX_BLUR_BIND_SRV_INPUT_SRC输出为rw_outputUAVFFX_BLUR_BIND_UAV_OUTPUT资源标识符定义见 ffx_blur_resources.hFFX_BLUR_RESOURCE_IDENTIFIER_INPUT_SRC 1、FFX_BLUR_RESOURCE_IDENTIFIER_OUTPUT 2。重写回调后即可对接自定义纹理名称与格式。3.3 通过自定义 main 函数集成除了 C 宿主 APIBlur 也支持通过自己的 computemain函数直接集成。核心要求是必须定义FFX_BLUR_TILE_SIZE_X与FFX_BLUR_TILE_SIZE_Y宏一般均为 8源码默认值也如此见 ffx_blur.h。HLSL 入口示例#include blur/ffx_blur_callbacks_hlsl.h #include blur/ffx_blur_blur.h [numthreads(FFX_BLUR_TILE_SIZE_X, FFX_BLUR_TILE_SIZE_Y, 1)] void CS( uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID, uint3 DispatchThreadID : SV_DispatchThreadID) { // Run FidelityFX - Blur ffxBlurPass(int2(DispatchThreadID.xy), int2(LocalThreadId.xy), int2(WorkGroupId.xy)); }GLSL 入口示例#include blur/ffx_blur_callbacks_glsl.h #include blur/ffx_blur_blur.h layout (local_size_x FFX_BLUR_TILE_SIZE_X, local_size_y FFX_BLUR_TILE_SIZE_Y, local_size_z 1) in; void main() { // Run FidelityFX Blur ffxBlurPass( FfxInt32x2(gl_GlobalInvocationID.xy), FfxInt32x2(gl_LocalInvocationID.xy), FfxInt32x2(gl_WorkGroupID.xy)); }其中ffxBlurPass会进一步把三个 ID 连同ImageSize()来自常量缓冲区cbBLUR的imageSize字段一起传给真正的算法函数ffxBlur。CPU 侧 Dispatch 时 Y 维默认使用FFX_BLUR_DISPATCH_Y 8即一个工作组在 Y 方向覆盖 8 个 tile 高度。四、Under the Hood三步算法与复杂度分析4.1 单趟三步骤算法Blur 采用三步算法通过线程组共享内存存储中间模糊结果从而在一次 compute dispatch内完成传统上需要两趟可分离滤波的工作Pre-fill预填充阶段从图像源填充缓存对首批 tile 执行水平模糊Loop top-down自上而下主循环从图像源填充缓存并做水平模糊 → 基于缓存结果做垂直模糊 → 写入目标资源Loop over the last few tiles尾部收尾循环仅对最后几个 tile 做垂直模糊并写入目标资源。4.2 复杂度理论Dispatch 时间复杂度Wave 执行时间复杂度Group Shared Memory 空间复杂度O(W * H * K)O(H * K)O(Th * (Tw K))其中W图像宽度Image WidthH图像高度Image HeightK1D 内核尺寸1D Kernel SizeTw模糊 tile 宽度Blur Tile Size XTh模糊 tile 高度Blur Tile Size Y从源码注释ffx_blur.h可以看到对算法的精确定义图像在缓存到 LDS 的同时进行水平模糊当所有 LDS tile 填满后在 LDS 上执行垂直模糊结果写入 UAV 作为最终输出。水平模糊的负载量image_load指令数会随FFX_BLUR_OPTION_KERNEL_DIMENSION线性增长这也是大内核如 21x21成本的主要来源。4.3 工作分布Work DistributionBlur 使用8x8 线程组每个线程组负责图像中的一个 tilethreadgroup 与 tile 一一对应。工作分布受以下#define影响FFX_BLUR_TILE_SIZE_X/FFX_BLUR_TILE_SIZE_Ytile 尺寸默认 8FFX_BLUR_DISPATCH_YY 方向 dispatch 维度默认 8决定每个工作组纵向覆盖的 tile 数FFX_BLUR_OPTION_KERNEL_DIMENSION内核维度直接决定预填充 tile 数量NUM_PREFILL_TILES_OUTPUT_CACHE DIV_AND_ROUND_UP(kernel, TILE_SIZE_Y)例如 3/5/7 内核预填充 1 个 tile9~15 预填充 2 个17~21 预填充 3 个见 ffx_blur.h。4.4 共享内存tile 环形缓冲区Blur 在共享内存中开辟一块区域作为tile 环形缓冲区ring buffer来存放中间结果与单个 tile 对应的线程组先采样源图像并执行水平模糊把结果写入共享内存随后该线程组从共享内存读取中间结果执行垂直模糊再把完全模糊后的图像写入目标纹理。实现层面的优化细节同样定义于 ffx_blur.h环形缓冲 tile 数NUM_TILES_OUTPUT_CACHE在FFX_BLUR_OPTION_KERNEL_DIMENSION 7时为 8否则为 4快速取模借助FAST_MOD(x, y) x (y-1)用位与代替取模要求 tile 数为 2 的幂降低 ALU 开销LDS 打包默认开启BLUR_GROUPSHARED_MEMORY_PK_UINT将 RG 两通道的 FP16 打包进单个 32 位无符号整数PackF2/UnpackToF2见 ffx_blur.hB 通道单独使用 FP32 以避免 bank conflict历史遗留选项BLUR_GROUPSHARED_MEMORY_SOA与BLUR_GROUPSHARED_MEMORY_HALF已被标记为 Deprecated边界钳制默认启用clampBLUR_DISABLE_CLAMP 0图像边缘采样坐标被钳制到[0, ImageSize-1]区间保证边界像素正确BLUR_OPTIMIZED_CLAMP为实验性开关。五、配套示例与调试对照samples/blur仓库同时提供了配套示例文档 dependencies/FidelityFX-SDK/docs/samples/blur.md该示例对应 dependencies/FidelityFX-SDK/samples/blur 目录用于演示与对比单趟高斯模糊相对标准两趟可分离模糊的性能优势支持 Windows DirectX 12 与 Vulkan。示例 UI 提供的可调参数与本文上述 API 参数一一对应UI 元素取值控制内容AlgorithmFidelityFX Blur, Single Pass Filter, Multi-pass Separable Filter, Multi-pass Separable Filter Transpose切换当前使用的算法FFX Blur / 标准多趟可分离滤波对照Gaussian Kernel Sigma1.6, 2.8, 4.0切换生成高斯内核所用的 sigmaKernel Size3x3, 5x5, ..., 21x21切换模糊内核尺寸Floating Point MathUse FP32, Use FP16切换 FP32 / FP16 实现Display the differenceOn/Off开关对比模式Comparison mode settingsCompare Algorithm, Compare Gaussian Sigma, Compare Kernel Size, Compare FP Math对比模式下对四个维度分别做差Diff Factor1.0..10.0显示差值时的放大倍数对比模式的实现逻辑是把Compare Algorithm下拉框所选算法连同其 sigma、尺寸、数学精度设置生成的图像与Algorithm下拉框所选算法生成的图像相减由于差异可能极小Diff Factor滑杆会把差值乘以指定倍数后再显示到屏幕上。该示例是验证本文第 2 节各参数实际效果的最直接工具。六、进一步阅读与参考资料GDC 2019: A Blend of GCN Optimization Color Processing,Part I: Store Caching in Separable Filters本篇文档共享内存环形缓存设计的理论来源见原文档 Further Reading 一节GDC 2018: Engine Optimization Hot LapRastergrid: Efficient Blur w/ Linear Sampling仓库内的相关深入材料还包括FidelityFX SDK 结构说明、FFX API 集成指南以及 FidelityFX Blur 命名规范若需在运行时动态切换内核可参考宿主侧实现 dependencies/FidelityFX-SDK/sdk/src/components/blur/ffx_blur.cpp。小结FidelityFX Blur 1.1 的价值在于用一次 compute dispatch 完成传统两趟可分离高斯模糊的全部工作宿主侧通过ffxBlurContextCreate/ffxBlurContextDispatch/ffxBlurContextDestroy三个 API 即可完整接入GPU 侧以 8x8 tile 为单位利用 LDS 环形缓冲区缓存水平模糊结果配合 2 的幂 tile 数位运算取模、FP16 打包等优化手段压低开销三种 sigma1.6/2.8/4.0与十档内核尺寸3x3~21x21通过位掩码灵活组合FP32/FP16 双精度变体可按需选择。无论你是通过 C 宿主 API 快速集成还是借助回调与自定义 main 函数深度定制本文给出的参数表与源码路径都能帮助你定位到对应实现。赞分享图形学游戏开发【免费下载链接】dlssg-to-fsr3Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).项目地址https://gitcode.com/gh_mirrors/dl/dlssg-to-fsr3点击查看免费下载相关推荐FidelityFX Blur 示例详解单次调度高斯模糊的算法原理、UI 参数与 SDK 集成实战FidelityFX Blur 示例详解单次调度高斯模糊的算法原理、UI 参数与 SDK 集成实战 FidelityFX Blur 示例演示了 AMD Fid图形学游戏开发FidelityFX FSR2 时间超分辨率技术深度解析从算法原理到集成实战dlssg-to-fsr3 仓库FidelityFX FSR2 时间超分辨率技术深度解析从算法原理到集成实战dlssg to fsr3 仓库 FSR2FidelityFX Super图形学游戏开发dlssg-to-fsr3 核心依赖解读AMD FidelityFX SDK 1.1 版本新特性、FSR 3.1 帧生成与 FSR API 全解析dlssg to fsr3 核心依赖解读AMD FidelityFX SDK 1.1 版本新特性、FSR 3.1 帧生成与 FSR API 全解析 本文围绕本图形学游戏开发上一篇SilentPatch终极修复指南让GTA经典三部曲在现代电脑上完美运行下一篇OpenCore Legacy Patcher终极指南3个简单步骤让老Mac免费升级最新macOS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考