FidelityFX Brixelizer GI 1.0.1
FidelityFX Brixelizer GI 是一种基于计算、高度优化的全局光照技术,使用 HLSL 实现。
目录
要求
HLSLCS_6_6
集成指南
FidelityFX Brixelizer GI
API
// =============================================================================// Initialize/destroy the FFX Brixelizer GI backend// =============================================================================
FfxBrixelizerGIContextDescription desc = {};
desc.flags = ...; ///< A bit field representings various options.desc.internalResolution = ...; ///< The scale at which Brixelizer GI will output GI at internally. The output will be internally upscaled to the specified displaySize.desc.displaySize = ...; ///< The size of the presentation resolution targeted by the upscaling process.desc.backendInterface = ffxGetInterface(...); ///< An implementation of the FidelityFX backend for use with Brixelizer.
FfxBrixelizerGIContext context = {};FfxErrorCode error = ffxBrixelizerGIContextCreate(&context, &desc);assert(error == FFX_OK);
// ...
FfxErrorCode error = ffxBrixelizerGIContextDestroy(&context);assert(error == FFX_OK);
// =============================================================================// Brixelizer GI frame update// =============================================================================
FfxBrixelizerGIDispatchDescription desc = {};
desc.view = ...; ///< The view matrix for the scene in row major order.desc.projection = ...; ///< The projection matrix for the scene in row major order.desc.prevView = ...; ///< The view matrix for the previous frame of the scene in row major order.desc.prevProjection = ...; ///< The projection matrix for the scene in row major order.
desc.cameraPosition = ...; ///< A 3-dimensional vector representing the position of the camera.desc.startCascade = ...; ///< The index of the start cascade for use with ray marching with Brixelizer.desc.endCascade = ...; ///< The index of the end cascade for use with ray marching with Brixelizer.desc.rayPushoff = ...; ///< The distance from a surface along the normal vector to offset the diffuse ray origin.desc.sdfSolveEps = ...; ///< The epsilon value for ray marching to be used with Brixelizer for diffuse rays.desc.specularRayPushoff = ...; ///< The distance from a surface along the normal vector to offset the specular ray origin.desc.specularSDFSolveEps = ...; ///< The epsilon value for ray marching to be used with Brixelizer for specular rays.desc.tMin = ...; ///< The TMin value for use with Brixelizer.desc.tMax = ...; ///< The TMax value for use with Brixelizer.
desc.environmentMap = ...; ///< The environment map.desc.prevLitOutput = ...; ///< The lit output from the previous frame.desc.depth = ...; ///< The input depth buffer.desc.historyDepth = ...; ///< The previous frame input depth buffer.desc.normal = ...; ///< The input normal buffer.desc.historyNormal = ...; ///< The previous frame input normal buffer.desc.roughness = ...; ///< The resource containing roughness information.desc.motionVectors = ...; ///< The input motion vectors texture.desc.noiseTexture = ...; ///< The input blue noise texture.
desc.normalsUnpackMul = ...; ///< A multiply factor to transform the normal to the space expected by Brixelizer GI.desc.normalsUnpackAdd = ...; ///< An offset to transform the normal to the space expected by Brixelizer GI.desc.isRoughnessPerceptual = ...; ///< A boolean to describe the space used to store roughness in the materialParameters texture. If false, we assume roughness squared was stored in the Gbuffer.desc.roughnessChannel = ...; ///< The channel to read the roughness from the roughness texturedesc.roughnessThreshold = ...; ///< Regions with a roughness value greater than this threshold won't spawn specular rays.desc.environmentMapIntensity = ...; ///< The value to scale the contribution from the environment map.desc.motionVectorScale = ...; ///< The scale factor to apply to motion vectors.
desc.sdfAtlas = ...; ///< The SDF Atlas resource used by Brixelizer.desc.bricksAABBs = ...; ///< The brick AABBs resource used by Brixelizer.for (uint32_t i = 0; i < 24; ++i) { desc.cascadeAABBTrees[i] = ...; ///< The cascade AABB tree resources used by Brixelizer. desc.cascadeBrickMaps[i] = ...; ///< The cascade brick map resources used by Brixelizer.}
desc.outputDiffuseGI = ...; ///< A texture to write the output diffuse GI calculated by Brixelizer GI.desc.outputSpecularGI = ...; ///< A texture to write the output specular GI calculated by Brixelizer GI.
desc.brixelizerContext = ...; ///< A pointer to the Brixelizer context for use with Brixelizer GI.
FfxCommandList commandList = ffxGetCommandList(...);
FfxErrorCode error = ffxBrixelizerGIContextDispatch(&context, &desc, commandList);assert(error == FFX_OK);
// =============================================================================// Brixelizer GI debug visualization// =============================================================================
FfxBrixelizerGIDebugDescription desc = {};
desc.view = ...; // The view matrix for the scene in row major order.desc.projection = ...; // The projection matrix for the scene in row major order.desc.startCascade = ...; // The index of the start cascade for use with ray marching with Brixelizer.desc.endCascade = ...; // The index of the end cascade for use with ray marching with Brixelizer.
desc.outputSize = ...; // The dimensions of the output texture.
desc.debugMode = ...; // The mode for the debug visualization. See <c><i>FfxBrixelizerGIDebugMode</i></c>.
desc.depth = ...; // The input depth buffer.desc.normal = ...; // The input normal buffer.
desc.sdfAtlas = ...; // The SDF Atlas resource used by Brixelizer.desc.bricksAABBs = ...; // The brick AABBs resource used by Brixelizer.for (uint32_t i = 0; i < 24; ++i) { desc.cascadeAABBTrees[24]; // The cascade AABB tree resources used by Brixelizer. desc.cascadeBrickMaps[24]; // The cascade brick map resources used by Brixelizer.}
desc.outputDebug = ...; // The output texture for the debug visualization.
desc.brixelizerContext = ...; // A pointer to the Brixelizer context for use with Brixelizer GI.
FfxCommandList = ffxGetCommandList(...);
FfxErrorCode error = ffxBrixelizerGIContextDebugVisualization(&context, &desc, commandList);assert(error == FFX_OK);算法概述
FidelityFX Brixelizer GI 是 AMD GI-1.0 的简化实现。
它接收应用程序的 G-Buffer 资源以及 Brixelizer 的输出资源,以生成漫射和镜面 GI 输出。
由于 Brixelizer 的距离场中缺乏材质信息,我们维护了一个内部辐射缓存,该缓存由前几帧的照明输出来填充。
仅包含直接照明将产生 1 次反弹的漫射 GI,而包含前一帧的合成输出则可以免费获得多次反弹。
接下来,我们在深度缓冲区中可见的表面上生成屏幕探针,并使用 Brixelizer 拍摄光线,并对辐射缓存进行采样以进行着色。
屏幕探针在内部存储在 8x8 的八面体映射中

这些屏幕探针随后通过在共享内存中进行并行规约,将 8x8 的入射辐射值投影到存储在每个有效砖块上的二阶球谐函数上,从而用于馈送世界空间辐射缓存。
最终的漫射 GI 输出通过将最近的 SH 探针投影到 G-Buffer 法线上来解析。
对于镜面 GI,我们在四分之一分辨率下进行预跟踪,以确定命中点的砖块 ID,然后使用全分辨率调度直接光线步进砖块,找到命中点并采样辐射缓存。
更新后,您可以将漫射和镜面 GI 输出合成到您的直接照明输出中,就像处理基于图像的照明一样。通常通过将其连接到 Epic 的分段近似值。
实现
资源
用户创建的资源
| 名称 | 类型 | 格式/步长 | 尺寸/字节大小 |
|---|---|---|---|
| 输出漫射 GI | Texture2D | RGBA16_FLOAT | displaySize.width x displaySize.height |
| 输出镜面 GI | Texture2D | RGBA16_FLOAT | displaySize.width x displaySize.height |
| 调试输出 | Texture2D | 用户定义的 RGB 格式 | displaySize.width x displaySize.height |
内部帧持久化资源
下表列出了 Brixelizer 上下文内部管理的所有结构化缓冲区。
| 名称 | 格式/步长 | 长度/尺寸 | 描述 |
|---|---|---|---|
BrixelizerGI_RadianceCache | R11G11B10_FLOAT | FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2 x FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2 x FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2 | 一个 3D 纹理,包含每个砖块体积内的入射直接照明,使用 4x4x4 纹理单元表示。 |
BrixelizerGI_StaticGITarget0 | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 用于存储内部漫射 GI 输出的两个乒乓纹理之一。 |
BrixelizerGI_StaticGITarget1 | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 用于存储内部漫射 GI 输出的两个乒乓纹理之一。 |
BrixelizerGI_StaticScreenProbes0 | R16G16B16A16_FLOAT | probeBufferWidth x probeBufferHeight | 用于存储屏幕探针输出的两个乒乓纹理之一。 |
BrixelizerGI_StaticScreenProbes1 | R16G16B16A16_FLOAT | probeBufferWidth x probeBufferHeight | 用于存储屏幕探针输出的两个乒乓纹理之一。 |
BrixelizerGI_SpecularTarget0 | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 用于存储内部镜面 GI 输出的两个乒乓纹理之一。 |
BrixelizerGI_SpecularTarget1 | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 用于存储内部镜面 GI 输出的两个乒乓纹理之一。 |
BrixelizerGI_DisocclusionMask | R8_UNORM | internalSize.width x internalSize.height | 一个存储生成的遮挡消除蒙版的纹理,用于拒绝历史记录。 |
BrixelizerGI_StaticScreenProbesStat | R16G16B16A16_FLOAT | tileBufferWidth x tileBufferHeight | 一个存储屏幕探针平均颜色的纹理。 |
BrixelizerGI_TempSpawnMask | R32_UINT | tileBufferWidth x tileBufferHeight | 一个存储屏幕探针生成信息的纹理。 |
BrixelizerGI_TempSpecularPretraceTarget | R32_UINT | tileBufferWidth * 2 x tileBufferHeight * 2 | 一个存储镜面跟踪命中点砖块 ID 的纹理。 |
BrixelizerGI_TempRandSeed | R8_UINT | tileBufferWidth x tileBufferHeight | 一个存储屏幕探针随机种子的纹理。 |
BrixelizerGI_RaySwapIndirectArgs | UINT32 | 4 * sizeof(FfxUInt32) | 一个存储间接调度参数的缓冲区。 |
BrixelizerGI_DownsampledDepth | R32_FLOAT | internalSize.width x internalSize.height | 一个存储下采样深度的纹理。 |
BrixelizerGI_DownsampledHistoryDepth | R32_FLOAT | internalSize.width x internalSize.height | 一个存储下采样历史深度的纹理。 |
BrixelizerGI_DownsampledNormals | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 一个存储下采样法线的纹理。 |
BrixelizerGI_DownsampledHistoryNormals | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 一个存储下采样历史法线的纹理。 |
BrixelizerGI_DownsampledRoughness | R8_UNORM | internalSize.width x internalSize.height | 一个存储下采样粗糙度的纹理。 |
BrixelizerGI_DownsampledMotionVectors | R16G16_FLOAT | internalSize.width x internalSize.height | 一个存储下采样运动矢量的纹理。 |
BrixelizerGI_DownsampledLitOutput | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 一个存储下采样前几帧着色输出的纹理。 |
BrixelizerGI_DownsampledDiffuseGI | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 一个存储上采样前的输出漫射 GI 的纹理。 |
BrixelizerGI_DownsampledSpecularGI | R16G16B16A16_FLOAT | internalSize.width x internalSize.height | 一个存储上采样前的输出镜面 GI 的纹理。 |
BrixelizerGI_BrickSH | UINT32x2 | FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x2) * 9 | 一个存储砖块处球谐函数的探针的缓冲区。 |
BrixelizerGI_BrickDirectSH | UINT32x2 | FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x2) * 9 | 一个存储砖块处入射直接照明(作为二阶球谐函数)的缓冲区。 |
BrixelizerGI_BrickSHState | UINT32x4 | FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x4) | 一个存储屏幕探针采样方向(作为二阶球谐函数)的缓冲区。 |
BrixelizerGI_StaticProbeSH | UINT32x2 | tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x2) * 9 | 一个存储屏幕探针球谐函数表示的缓冲区。 |
BrixelizerGI_TempProbeSH | UINT32x2 | tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x2) * 9 | 一个存储屏幕探针球谐函数表示的缓冲区。 |
BrixelizerGI_StaticProbeInfo | UINT32x4 | tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x4) * 9 | 一个存储屏幕探针打包信息的缓冲区。 |
BrixelizerGI_TempProbeInfo | UINT32x4 | tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x4) * 9 | 一个存储屏幕探针打包信息的缓冲区。 |
以下是 Brixelizer GI 上下文管理的不同常量缓冲区的列表。
| 名称 | 格式 | 描述 |
|---|---|---|
FfxBrixelizerGI_Constants | FfxBrixelizerGIConstants | 描述 Brixelizer GI 上下文的参数。 |
FfxBrixelizerGI_PassConstants | FfxBrixelizerGIPassConstants | 描述发射辐射传递通道的参数。 |
FfxBrixelizerGI_ScalingConstants | FfxBrixelizerGIScalingConstants | 用于下采样和上采样常数的参数。 |
Brixelizer_ContextInfoBuffer | FfxBrixelizerContextInfo | 描述 Brixelizer 上下文的参数。 |
Brixelizer_CascadeInfoBuffer | FfxBrixelizerCascadeInfo | 描述单个级联的参数。 |
着色器通道
以下是 Brixelizer GI 使用的所有着色器通道列表。
| 功能 | 文件 | 组维度 | 描述 |
|---|---|---|---|
FfxBrixelizerGIDownsample | ffx_brixelizergi_main.h | 8 x 8 x 1 | 如果使用非原生内部分辨率比例,则下采样输入资源。 |
FfxBrixelizerGIGenerateDisocclusionMask | ffx_brixelizergi_main.h | 8 x 8 x 1 | 在 BrixelizerGI_DisocclusionMask 中生成遮挡消除蒙版。 |
FfxBrixelizerGIPrepareClearCache | ffx_brixelizergi_radiance_cache_update.h | 1 x 1 x 1 | 将间接调度参数写入 BrixelizerGI_RaySwapIndirectArgs 以清除辐射缓存。 |
FfxBrixelizerGIClearCache | ffx_brixelizergi_radiance_cache_update.h | 64 x 1 x 1 | 清除无效砖块的辐射缓存条目。 |
FfxBrixelizerGIEmitPrimaryRayRadiance | ffx_brixelizergi_radiance_cache_update.h | 8 x 8 x 1 | 将上一帧的重投影辐射注入辐射缓存。 |
FfxBrixelizerGIPropagateSH | ffx_brixelizergi_radiance_cache_update.h | 64 x 1 x 1 | 将每个砖块处的 SH 探针传播到相邻砖块。 |
FfxBrixelizerGISpawnScreenProbes | ffx_brixelizergi_main.h | 8 x 8 x 1 | 在深度缓冲区上生成新的屏幕探针并输出探针信息。 |
FfxBrixelizerGIReprojectScreenProbes | ffx_brixelizergi_main.h | 8 x 8 x 1 | 将前一帧的屏幕探针重投影到当前帧。 |
FfxBrixelizerGIFillScreenProbes | ffx_brixelizergi_main.h | 8 x 4 x 1 | 使用 Brixelizer 跟踪漫射光线,以将新的辐射信息注入屏幕探针。 |
FfxBrixelizerGISpecularPreTrace | ffx_brixelizergi_main.h | 8 x 4 x 1 | 使用 Brixelizer 跟踪镜面光线,并输出命中点的砖块 ID。 |
FfxBrixelizerGIReprojectGI | ffx_brixelizergi_main.h | 8 x 8 x 1 | 将前一帧的漫射和镜面 GI 输出重投影到当前帧。 |
FfxBrixelizerGISpecularTrace | ffx_brixelizergi_main.h | 8 x 4 x 1 | 通过从镜面预跟踪通道光线步进砖块并采样辐射缓存来解析镜面输出。 |
FfxBrixelizerGIProjectScreenProbes | ffx_brixelizergi_main.h | 8 x 8 x 1 | 将八面体屏幕探针投影到球谐函数。 |
FfxBrixelizerGIEmitIrradianceCache | ffx_brixelizergi_main.h | 8 x 8 x 1 | 使用球谐函数屏幕探针更新辐射缓存。 |
FfxBrixelizerGIInterpolateScreenProbes | ffx_brixelizergi_main.h | 8 x 8 x 1 | 解析最终的漫射和镜面 GI 输出并执行时间累积。 |
FfxBrixelizerGIBlurGI | ffx_brixelizergi_main.h | 8 x 8 x 1 | 空间上对漫射和镜面 GI 输出进行去噪。 |
FfxBrixelizerGIUpsample | ffx_brixelizergi_main.h | 8 x 8 x 1 | 如果使用非原生内部分辨率比例,则对漫射和镜面 GI 输出进行上采样。 |