资讯详情

FidelityFX Blur 示例详解:单次调度高斯模糊的算法原理、UI 参数与 SDK 集成实战

📅 2026/10/4 1:56:08 | 华诺云谱 👁 阅读
FidelityFX Blur 示例详解:单次调度高斯模糊的算法原理、UI 参数与 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 示例演示了 AMD FidelityFX SDK 中的单次调度single-pass高斯模糊效果它在功能上与标准两遍可分离separable高斯模糊完全一致但通过线程组共享内存group shared memory一次 compute dispatch 即可完成性能更优。本文将围绕该示例的 UI 参数、比较模式与配置文件展开实操讲解并深入 技术文档 与 GPU/主机端源码说明其算法流程、复杂度以及如何在自有应用中通过 C API 与回调自定义集成。示例概览与运行要求本示例位于dependencies/FidelityFX-SDK/samples/blur/由 Cauldron 框架下的BlurRenderModule驱动blurrendermodule.cpp。它把模糊效果直接作用于当前场景颜色缓冲每一帧先将上游渲染模块输出的颜色纹理拷贝到输入纹理执行选定的模糊算法后再写回颜色缓冲供后续 ToneMapping 等模块继续使用。这种输入拷贝 → 模糊 → 输出回写的链路正好模拟了真实渲染管线中后处理模糊的典型接入方式。示例运行的基本要求如下操作系统Windows图形 APIDirectX(R) 12 或 Vulkan(R)Compute shader 层面的技术门槛详见技术文档为HLSLCS_6_0对应 SM 6.0 计算着色器GLSLversion 450除 FidelityFX Blur 本身外示例还内置了三套用于对比的基线模糊算法单遍盒式滤波Single Pass Box Filter、多遍可分离滤波Multi-pass Separable Filter以及带转置的多遍可分离滤波Multi-pass Separable Filter Transpose。这些基线管线全部由blur_baseline_filters_cs.hlslshaders 目录编译而来并在 blurrendermodule.cpp 中以不同的#define组合SINGLE_PASS_BOX_FILTER、MULTI_PASS_SEPARABLE_FILTER、TRANSPOSE_OUT、HALF_PRECISION等批量实例化出 FP16/FP32 两个精度、3 种 sigma、10 种核尺寸的完整管线矩阵。UI 元素与参数详解示例的 UI 由 blurrendermodule.cpp 中的Init方法注册集中在一组下拉框、复选框与滑块上。下表总结了每个元素及其控制的参数与文档表格一致并补充了源码中的可选值实现元素名称可选值说明AlgorithmNone、FidelityFX Blur、Single Pass Box Filter、Multi-pass Separable Filter、Multi-pass Separable Filter Transpose切换当前使用的模糊算法。选择FidelityFX Blur时会销毁并重建对应的 FfxBlurContext。Gaussian Kernel Sigma1.6, 2.8, 4.0切换生成高斯核所使用的 sigma 值。Kernel Size3x3, 5x5, ..., 21x21奇数尺寸切换模糊核尺寸共 10 档。Floating Point MathUse FP32, Use FP16在技术效果的 FP32 与 FP16 实现间切换。Display the differenceOn/Off开关比较模式Display the difference between two algorithms.复选框。Comparison mode settingsCompare Algorithm、Compare Gaussian Sigma、Compare Kernel Size、Compare FP Math与上方相同的选项但作用于比较模式的第二个算法。Diff Factor1.0..10.0显示比较差异时应用的放大倍数。从源码实现看这些 UI 选项与 SDK 主机端枚举是一一对应的sigma 选项对应 ffx_blur.h 中的FfxBlurKernelPermutation枚举FFX_BLUR_KERNEL_PERMUTATION_0/1/2分别表示 sigma 1.6、2.8、4.0核尺寸对应FfxBlurKernelSize位掩码枚举FFX_BLUR_KERNEL_SIZE_3x3…FFX_BLUR_KERNEL_SIZE_21x21共 10 个浮点精度对应FfxBlurFloatPrecisionFFX_BLUR_FLOAT_PRECISION_32BIT/FFX_BLUR_FLOAT_PRECISION_16BIT。示例在创建上下文时使用FFX_BLUR_KERNEL_PERMUTATIONS_ALL与FFX_BLUR_KERNEL_SIZE_ALL一次启用全部 sigma 与核尺寸组合见 CreateBlurContexts而在每次 dispatch 时才按 UI 选择传入具体的置换与尺寸。比较模式Comparison mode勾选Display the difference between two algorithms复选框后比较模式被激活。其工作方式是将Compare Algorithm下拉框所选算法及其 sigma、核尺寸、浮点精度配置下生成的图像从Algorithm下拉框所选算法及对应配置生成的图像中逐像素相减。从 Execute 的代码可以看到完整流程主算法结果写入BLUR_ComparisonOutput1比较算法结果写入BLUR_ComparisonOutput2最终由blur_compare_filters_cs.hlslshaders 目录编译的ComparisonPass计算两幅图像的差异并写入输出缓冲差异值乘以Diff Factor后显示。由于极小的数值差异在屏幕上几乎不可见Diff Factor滑块范围 1.0 到 10.0用于将差异放大后再显示便于肉眼观察 FP16/FP32 精度差异、不同 sigma 或不同核尺寸对结果的影响。示例配置blurconfig.json示例的场景与渲染管线由 blurconfig.json 控制{ FidelityFX Blur: { RenderModules: [ RasterShadowRenderModule, GBufferRenderModule, LightingRenderModule, SkyDomeRenderModule, TranslucencyRenderModule, BlurRenderModule, ToneMappingRenderModule ], Content: { Scenes: [ ../media/Locomotive/Locomotive.gltf ], Camera: Camera_4, DiffuseIBL: ../media/IBL/hansaplatz_Diffuse.dds, SpecularIBL: ../media/IBL/hansaplatz_Specular.dds, SkyMap: ../media/IBL/hansaplatz_Specular.dds, SceneExposure: 0.85 } } }其中RenderModules数组按顺序声明了渲染模块流水线先由 GBuffer、Lighting、SkyDome、Translucency 等模块生成场景颜色缓冲BlurRenderModule作为后处理滤镜插在中间最后由ToneMappingRenderModule完成色调映射输出到屏幕。Content段则指定了示例加载的 GLTF 场景、摄像机与 IBL 环境贴图资源。这些路径是相对于示例自身目录的局部路径实际资源位于 Cauldron 框架的媒体目录中。关于示例的通用控制方式、配置说明与 Cauldron UI 操作细节可参阅 运行示例指南。算法原理三次步骤合并为单次 dispatch与两遍可分离模糊先水平后垂直各一次全屏 dispatch不同FidelityFX Blur 将算法拆成三个步骤并利用线程组共享内存缓存中间结果在单次 compute dispatch内完成技术文档Under the hood一节以及 ffx_blur.h 中ffxBlur的实现预填充步骤Pre-fill从图像源读取像素执行水平模糊将结果填充进共享内存缓存自上而下循环Loop top-down继续填充下一块水平模糊结果 → 从缓存读取中间结果做垂直模糊 → 将最终结果写入目标资源UAV末尾若干 tile 收尾循环对最后几行 tile 仅执行垂直模糊并写出。对应复杂度为Dispatch 时间复杂度Wave 执行时间复杂度共享内存空间复杂度O(W * H * K)O(H * K)O(Th * (Tw K))其中W为图像宽度H为图像高度K为一维核尺寸Tw/Th分别为 tile 的 X / Y 尺寸。Work distribution工作分配Blur 使用 8x8 线程组每个线程组负责图像中的一个 tile。工作分配受以下#define影响源码 ffx_blur.hFFX_BLUR_TILE_SIZE_X/FFX_BLUR_TILE_SIZE_Y本地线程组处理的 tile 尺寸默认均为 8FFX_BLUR_DISPATCH_Ydispatch 在 Y 方向每个 workgroup 覆盖的 tile 数量默认 8。Shared memory共享内存共享内存以tile 环形缓冲区ring-buffer的形式保存中间结果。线程组先对源图像采样并做水平模糊把结果存入共享内存之后再从共享内存读取这些中间结果执行垂直模糊将最终结果写入目标纹理。环形缓冲的设计使缓存容量与核尺寸解耦并通过FAST_MOD对 2 的幂做位与取模快速计算缓存槽位避免使用更耗 ALU 的取模运算。源码中相关的关键配置ffx_blur.h包括NUM_TILES_OUTPUT_CACHE核尺寸大于 7 时为 8否则为 4使用 2 的幂便于位运算NUM_PREFILL_TILES_OUTPUT_CACHE预填充 tile 数按ceil(KernelDimension / TileSizeY)计算例如核 3/5/7 时为 19~15 时为 217~21 时为 3BLUR_GROUPSHARED_MEMORY_PK_UINT默认开启将 RG 两个通道打包进一个 32 位无符号整数以压缩共享内存占用B 通道单独存放以避免 bank conflictBLUR_ENABLE_INPUT_CACHE默认关闭——源码注释指出该输入缓存当前反而拖慢算法。SDK 集成C API 与回调自定义C SDK 集成将 Blur 效果接入自有应用的最简单方式是使用 FFX SDK 的 C API技术文档示例调用点与示例 ExecuteBlurEffect 完全一致// 初始化 FFX backend 与 blur context只需一次 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); // 执行模糊可多次调用 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); // 使用完毕清理资源 ffxBlurContextDestroy(blurContext);主机端接口声明可查阅 ffx_blur.h其中FfxBlurContextDescription的kernelPermutations/kernelSizes是位掩码可在创建上下文时裁剪需要的 sigma 与核尺寸组合以缩小着色器编译集合ffxBlurContextDispatch每次调用时再从已启用的集合中选取具体的kernelPermutation与kernelSize。通过回调与自定义 main 函数定制Blur 在ffx_blur_callbacks_hlsl.h与ffx_blur_callbacks_glsl.h中提供了核权重与 I/O 函数的默认实现SDK 使用者可以覆盖它们以适配自己的应用。为了达到最高性能Blur 期望 1D 核权重内嵌在编译后的着色器中要求如下函数签名中的核权重类型使用FfxFloat32或FfxFloat16取决于是否支持半精度这两个类型定义在 ffx_core.h 中需要定义一组唯一的静态数组核权重表示按降序排列的归一化高斯权重分布。核权重覆盖示例#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); }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还可以通过自定义main函数接入此时必须定义FFX_BLUR_TILE_SIZE_X与FFX_BLUR_TILE_SIZE_Y宏一般均设为 8#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)); }GPU 端ffxBlurPass的薄封装位于 ffx_blur_blur.h它将线程 ID 与图像尺寸传入ffxBlur核心函数实际水平/垂直模糊循环与 LDS 缓存逻辑均在 ffx_blur.h 中实现。源码导读与延伸阅读若希望进一步研究示例或技术实现可从以下文件入手示例渲染模块blurrendermodule.cpp、blurrendermodule.h基线算法与对比着色器blur_baseline_filters_cs.hlsl、blur_compare_filters_cs.hlsl、blur_gaussian_blur_kernels.h主机端 APIffx_blur.hGPU 端实现ffx_blur.h、ffx_blur_callbacks_hlsl.h、ffx_blur_callbacks_glsl.h、ffx_blur_resources.h更多相关内容FidelityFX Blur 技术文档FidelityFX 命名规范运行示例指南赞分享图形学游戏开发【免费下载链接】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点击查看免费下载相关推荐TiXL Blur 算子完全指南图像模糊后处理原理、参数详解与实战配置TiXL Blur 算子完全指南图像模糊后处理原理、参数详解与实战配置 Blur 是 TiXL 开源实时动态图形引擎中位于 Lib.image.fx.blur音视频图形学桌面应用Three.js HorizontalBlurShader 详解水平高斯模糊着色器的原理、参数设置与两个实战集成方案Three.js HorizontalBlurShader 详解水平高斯模糊着色器的原理、参数设置与两个实战集成方案 本篇技术指南围绕 Three.js 官方前端3D渲染图形学jimp/plugin-blur 深度解析从快速模糊到高斯模糊的实现原理与版本演进jimp/plugin blur 深度解析从快速模糊到高斯模糊的实现原理与版本演进 jimp/plugin blur 是 jimp 图像处理库中的模糊插件图像处理上一篇终极指南Fluent UI微前端共享组件的跨应用版本管理策略下一篇IntelliJ IDEA 编译机制全解析Make、Rebuild、Compile 与编译器设置实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑