Skip to content

FidelityFX Brixelizer GI 1.0.1

FidelityFX Brixelizer GI is a compute-based, highly-optimized global illumination technique implemented in HLSL.

Table of Contents

Requirements

  • HLSL CS_6_6

Integration Guidelines

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 texture
desc.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);

Algorithm Overview

FidelityFX Brixelizer GI is a simplified implementation of AMD GI-1.0.

It takes in the G-Buffer resources of your application alongside the output resources from Brixelizer to generate Diffuse and Specular GI outputs.

High Level View

Due to the lack of material information in the distance field from Brixelizer, we maintain an internal radiance cache which is populated by the previous frames’ lighting output.

Radiance Cache

Including just direct lighting will result in 1-bounce diffuse GI, whereas including the composited output from the previous frame gives you multiple bounces effectively for free.

Radiance Cache

Next we spawn screen probes on the visible surfaces in the depth buffer and shoot rays using Brixelizer and sample the radiance cache for shading.

Probe Sampling

Screen probes are internally stored in an 8x8 octahedral mapping:

Screen Probes

These screen probes are then used to feed a world space irradiance cache by performing a parallel reduction in shared memory to project the 8x8 incoming radiance values on to 2nd order spherical harmonics that are stored at each valid brick.

Irradiance Cache

The final Diffuse GI output is resolved by projecting the nearest SH probe on to G-Buffer normal.

Probe Interpolation

For Specular GI we perform a pre-trace at quarter resolution to figure out the brick IDs at hit points and afterwards use a full-resolution dispatch to skip directly to ray-marching the bricks, finding the hit point and sample the radiance cache.

Specular GI

After the update you composite the diffuse and specular GI outputs into your direct lighting output the same way you would do with Image based lighting. Usually by plugging it into Epic’s split-sum approximation.

Implementation

Resources

User Created Resources

NameTypeFormat/StrideDimensions/Size in bytes
Output Diffuse GITexture2DRGBA16_FLOATdisplaySize.width x displaySize.height
Output Specular GITexture2DRGBA16_FLOATdisplaySize.width x displaySize.height
Debug OutputTexture2DA user defined RGB formatdisplaySize.width x displaySize.height

Internal Frame Persistent Resources

The following is a table of all structured buffers managed internally by the Brixelizer context.

NameFormat/StrideLength/DimensionsDescription
BrixelizerGI_RadianceCacheR11G11B10_FLOATFFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2 x FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2 x FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2A 3D texture containing the incoming direct lighting at each brick volume represented using 4x4x4 texels.
BrixelizerGI_StaticGITarget0R16G16B16A16_FLOATinternalSize.width x internalSize.heightOne of two ping-pong textures for storing internal Diffuse GI output.
BrixelizerGI_StaticGITarget1R16G16B16A16_FLOATinternalSize.width x internalSize.heightOne of two ping-pong textures for storing internal Diffuse GI output.
BrixelizerGI_StaticScreenProbes0R16G16B16A16_FLOATprobeBufferWidth x probeBufferHeightOne of two ping-pong textures for storing screen probes output.
BrixelizerGI_StaticScreenProbes1R16G16B16A16_FLOATprobeBufferWidth x probeBufferHeightOne of two ping-pong textures for storing screen probes output.
BrixelizerGI_SpecularTarget0R16G16B16A16_FLOATinternalSize.width x internalSize.heightOne of two ping-pong textures for storing internal Specular GI output.
BrixelizerGI_SpecularTarget1R16G16B16A16_FLOATinternalSize.width x internalSize.heightOne of two ping-pong textures for storing internal Specular GI output.
BrixelizerGI_DisocclusionMaskR8_UNORMinternalSize.width x internalSize.heightA texture that stores the generated disocclusion mask for rejecting history.
BrixelizerGI_StaticScreenProbesStatR16G16B16A16_FLOATtileBufferWidth x tileBufferHeightA texture that stores the average color of a screen probe.
BrixelizerGI_TempSpawnMaskR32_UINTtileBufferWidth x tileBufferHeightA texture that stores the spawn information for screen probes.
BrixelizerGI_TempSpecularPretraceTargetR32_UINTtileBufferWidth * 2 x tileBufferHeight * 2A texture that stores brick IDs at specular trace hits.
BrixelizerGI_TempRandSeedR8_UINTtileBufferWidth x tileBufferHeightA texture that stores the random seeds for screen probes.
BrixelizerGI_RaySwapIndirectArgsUINT324 * sizeof(FfxUInt32)A buffer that stores indirect dispatch arguments.
BrixelizerGI_DownsampledDepthR32_FLOATinternalSize.width x internalSize.heightA texture that stores the downsampled depth.
BrixelizerGI_DownsampledHistoryDepthR32_FLOATinternalSize.width x internalSize.heightA texture that stores the downsampled history depth.
BrixelizerGI_DownsampledNormalsR16G16B16A16_FLOATinternalSize.width x internalSize.heightA texture that stores the downsampled normals.
BrixelizerGI_DownsampledHistoryNormalsR16G16B16A16_FLOATinternalSize.width x internalSize.heightA texture that stores the downsampled history normals.
BrixelizerGI_DownsampledRoughnessR8_UNORMinternalSize.width x internalSize.heightA texture that stores the downsampled roughness.
BrixelizerGI_DownsampledMotionVectorsR16G16_FLOATinternalSize.width x internalSize.heightA texture that stores the downsampled motion vectors.
BrixelizerGI_DownsampledLitOutputR16G16B16A16_FLOATinternalSize.width x internalSize.heightA texture that stores the downsampled previous frames’ shading output.
BrixelizerGI_DownsampledDiffuseGIR16G16B16A16_FLOATinternalSize.width x internalSize.heightA texture that stores the output Diffuse GI prior to upsampling.
BrixelizerGI_DownsampledSpecularGIR16G16B16A16_FLOATinternalSize.width x internalSize.heightA texture that stores the output Specular GI prior to upsampling.
BrixelizerGI_BrickSHUINT32x2FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x2) * 9A buffer that stores the spherical harmonics probes at bricks.
BrixelizerGI_BrickDirectSHUINT32x2FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x2) * 9A buffer that stores the incoming direct lighting at bricks as second order spherical harmonics.
BrixelizerGI_BrickSHStateUINT32x4FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x4)A buffer that stores the direction of the screen probe sample as second order spherical harmonics.
BrixelizerGI_StaticProbeSHUINT32x2tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x2) * 9A buffer that stores the spherical harmonics representation ofthe screen probes.
BrixelizerGI_TempProbeSHUINT32x2tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x2) * 9A buffer that stores the spherical harmonics representation ofthe screen probes.
BrixelizerGI_StaticProbeInfoUINT32x4tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x4) * 9A buffer that stores packed information of screen probe.
BrixelizerGI_TempProbeInfoUINT32x4tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x4) * 9A buffer that stores packed information of screen probe.

The following is a list of the different constant buffers managed by the Brixelizer GI context.

NameFormatDescription
FfxBrixelizerGI_ConstantsFfxBrixelizerGIConstantsParameters describing the Brixelizer GI context.
FfxBrixelizerGI_PassConstantsFfxBrixelizerGIPassConstantsParameters describing the emit irradiance pass.
FfxBrixelizerGI_ScalingConstantsFfxBrixelizerGIScalingConstantsParameters for downsampling and upsampling constants.
Brixelizer_ContextInfoBufferFfxBrixelizerContextInfoParameters describing the Brixelizer context.
Brixelizer_CascadeInfoBufferFfxBrixelizerCascadeInfoParameters describing a single cascade.

Shader Passes

Here is a list of all the shader passes used by Brixelizer GI.

FunctionFileGroup DimensionsDescription
FfxBrixelizerGIDownsampleffx_brixelizergi_main.h8 x 8 x 1Downsample input resources if using a non-native internal resolution scale.
FfxBrixelizerGIGenerateDisocclusionMaskffx_brixelizergi_main.h8 x 8 x 1Generate a disocclusion mask into BrixelizerGI_DisocclusionMask.
FfxBrixelizerGIPrepareClearCacheffx_brixelizergi_radiance_cache_update.h1 x 1 x 1Write indirect dispatch arguments into BrixelizerGI_RaySwapIndirectArgs for clearing radiance cache.
FfxBrixelizerGIClearCacheffx_brixelizergi_radiance_cache_update.h64 x 1 x 1Clear radiance cache entries for invalidated bricks.
FfxBrixelizerGIEmitPrimaryRayRadianceffx_brixelizergi_radiance_cache_update.h8 x 8 x 1Inject reprojected radiance from the last frame into the radiance cache.
FfxBrixelizerGIPropagateSHffx_brixelizergi_radiance_cache_update.h64 x 1 x 1Propagate the SH probes at each brick into the neighboring bricks.
FfxBrixelizerGISpawnScreenProbesffx_brixelizergi_main.h8 x 8 x 1Spawn new screen probes on the depth buffer and output probe information.
FfxBrixelizerGIReprojectScreenProbesffx_brixelizergi_main.h8 x 8 x 1Reproject screen probes from the previous frame into the current frame.
FfxBrixelizerGIFillScreenProbesffx_brixelizergi_main.h8 x 4 x 1Trace diffuse rays using Brixelizer to inject new radiance information into screen probes.
FfxBrixelizerGISpecularPreTraceffx_brixelizergi_main.h8 x 4 x 1Trace specular rays using Brixelizer and output brick IDs at hit points.
FfxBrixelizerGIReprojectGIffx_brixelizergi_main.h8 x 8 x 1Reproject the diffuse and specular GI outputs from the previous frame into the current frame.
FfxBrixelizerGISpecularTraceffx_brixelizergi_main.h8 x 4 x 1Resolve specular output by ray marching the bricks from the Specular Pre Trace pass and sampling the radiance cache.
FfxBrixelizerGIProjectScreenProbesffx_brixelizergi_main.h8 x 8 x 1Project the octahedral screen probes into spherical harmonics.
FfxBrixelizerGIEmitIrradianceCacheffx_brixelizergi_main.h8 x 8 x 1Update the irradiance cache using spherical harmonics screen probes.
FfxBrixelizerGIInterpolateScreenProbesffx_brixelizergi_main.h8 x 8 x 1Resolve final diffuse and specular GI output and perform temporal accumulation.
FfxBrixelizerGIBlurGIffx_brixelizergi_main.h8 x 8 x 1Spatially denoise the diffuse and specular GI outputs.
FfxBrixelizerGIUpsampleffx_brixelizergi_main.h8 x 8 x 1Upscale diffuse and specular GI outputs if using a non-native internal resolution scale.