FidelityFX Brixelizer GI 1.0

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

Copied!

// =============================================================================
// Initialize/destroy the FFX Brixelizer GI backend
// =============================================================================

FfxBrixelizerGIContextDescription  desc = {};

desc.flags               = ...;
desc.internalResolution  = ...;
desc.displaySize         = ...;
desc.backendInterface    = ffxGetInterface (...);

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 = ...;
desc.projection = ...;
desc.prevView = ...;
desc.prevProjection = ...;

desc.cameraPosition = ...;
desc.startCascade = ...;
desc.endCascade = ...;
desc.rayPushoff = ...;
desc.sdfSolveEps = ...;
desc.specularRayPushoff = ...;
desc.specularSDFSolveEps = ...;
desc.tMin = ...;
desc.tMax = ...;

desc.environmentMap = ...;
desc.prevLitOutput = ...;
desc.depth = ...;
desc.historyDepth = ...;
desc.normal = ...;
desc.historyNormal = ...;
desc.roughness = ...;
desc.motionVectors = ...;
desc.noiseTexture = ...;

desc.normalsUnpackMul = ...;
desc.normalsUnpackAdd = ...;
desc.isRoughnessPerceptual = ...;
desc.roughnessChannel = ...;
desc.roughnessThreshold = ...;
desc.environmentMapIntensity = ...;
desc.motionVectorScale = ...;

desc.sdfAtlas = ...;
desc.bricksAABBs = ...;
for (uint32_t i = 0; i < 24; ++i) {
    desc.cascadeAABBTrees[i] = ...;
    desc.cascadeBrickMaps[i] = ...;
}

desc.outputDiffuseGI = ...;
desc.outputSpecularGI = ...;

desc.brixelizerContext = ...;

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 8×8 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 8×8 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

Name

Type

Format/Stride

Dimensions/Size in bytes

Output Diffuse GI

Texture2D

RGBA16_FLOAT

displaySize.width x displaySize.height

Output Specular GI

Texture2D

RGBA16_FLOAT

displaySize.width x displaySize.height

Debug Output

Texture2D

A user defined RGB format

displaySize.width x displaySize.height

Internal Frame Persistent Resources

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

Name

Format/Stride

Length/Dimensions

Description

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

A 3D texture containing the incoming direct lighting at each brick volume represented using 4x4x4 texels.

BrixelizerGI_StaticGITarget0

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

One of two ping-pong textures for storing internal Diffuse GI output.

BrixelizerGI_StaticGITarget1

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

One of two ping-pong textures for storing internal Diffuse GI output.

BrixelizerGI_StaticScreenProbes0

R16G16B16A16_FLOAT

probeBufferWidth x probeBufferHeight

One of two ping-pong textures for storing screen probes output.

BrixelizerGI_StaticScreenProbes1

R16G16B16A16_FLOAT

probeBufferWidth x probeBufferHeight

One of two ping-pong textures for storing screen probes output.

BrixelizerGI_SpecularTarget0

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

One of two ping-pong textures for storing internal Specular GI output.

BrixelizerGI_SpecularTarget1

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

One of two ping-pong textures for storing internal Specular GI output.

BrixelizerGI_DisocclusionMask

R8_UNORM

internalSize.width x internalSize.height

A texture that stores the generated disocclusion mask for rejecting history.

BrixelizerGI_StaticScreenProbesStat

R16G16B16A16_FLOAT

tileBufferWidth x tileBufferHeight

A texture that stores the average color of a screen probe.

BrixelizerGI_TempSpawnMask

R32_UINT

tileBufferWidth x tileBufferHeight

A texture that stores the spawn information for screen probes.

BrixelizerGI_TempSpecularPretraceTarget

R32_UINT

tileBufferWidth * 2 x tileBufferHeight * 2

A texture that stores brick IDs at specular trace hits.

BrixelizerGI_TempRandSeed

R8_UINT

tileBufferWidth x tileBufferHeight

A texture that stores the random seeds for screen probes.

BrixelizerGI_RaySwapIndirectArgs

UINT32

4 * sizeof(FfxUInt32)

A buffer that stores indirect dispatch arguments.

BrixelizerGI_DownsampledDepth

R32_FLOAT

internalSize.width x internalSize.height

A texture that stores the downsampled depth.

BrixelizerGI_DownsampledHistoryDepth

R32_FLOAT

internalSize.width x internalSize.height

A texture that stores the downsampled history depth.

BrixelizerGI_DownsampledNormals

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

A texture that stores the downsampled normals.

BrixelizerGI_DownsampledHistoryNormals

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

A texture that stores the downsampled history normals.

BrixelizerGI_DownsampledRoughness

R8_UNORM

internalSize.width x internalSize.height

A texture that stores the downsampled roughness.

BrixelizerGI_DownsampledMotionVectors

R16G16_FLOAT

internalSize.width x internalSize.height

A texture that stores the downsampled motion vectors.

BrixelizerGI_DownsampledLitOutput

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

A texture that stores the downsampled previous frames’ shading output.

BrixelizerGI_DownsampledDiffuseGI

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

A texture that stores the output Diffuse GI prior to upsampling.

BrixelizerGI_DownsampledSpecularGI

R16G16B16A16_FLOAT

internalSize.width x internalSize.height

A texture that stores the output Specular GI prior to upsampling.

BrixelizerGI_BrickSH

UINT32x2

FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x2) * 9

A buffer that stores the spherical harmonics probes at bricks.

BrixelizerGI_BrickDirectSH

UINT32x2

FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x2) * 9

A buffer that stores the incoming direct lighting at bricks as second order spherical harmonics.

BrixelizerGI_BrickSHState

UINT32x4

FFX_BRIXELIZER_MAX_BRICKS_X8 * sizeof(FfxUInt32x4)

A buffer that stores the direction of the screen probe sample as second order spherical harmonics.

BrixelizerGI_StaticProbeSH

UINT32x2

tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x2) * 9

A buffer that stores the spherical harmonics representation ofthe screen probes.

BrixelizerGI_TempProbeSH

UINT32x2

tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x2) * 9

A buffer that stores the spherical harmonics representation ofthe screen probes.

BrixelizerGI_StaticProbeInfo

UINT32x4

tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x4) * 9

A buffer that stores packed information of screen probe.

BrixelizerGI_TempProbeInfo

UINT32x4

tileBufferWidth * tileBufferHeight * sizeof(FfxUInt32x4) * 9

A buffer that stores packed information of screen probe.

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

Name

Format

Description

FfxBrixelizerGI_Constants

FfxBrixelizerGIConstants

Parameters describing the Brixelizer GI context.

FfxBrixelizerGI_PassConstants

FfxBrixelizerGIPassConstants

Parameters describing the emit irradiance pass.

FfxBrixelizerGI_ScalingConstants

FfxBrixelizerGIScalingConstants

Parameters for downsampling and upsampling constants.

Brixelizer_ContextInfoBuffer

FfxBrixelizerContextInfo

Parameters describing the Brixelizer context.

Brixelizer_CascadeInfoBuffer

FfxBrixelizerCascadeInfo

Parameters describing a single cascade.

Shader Passes

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

Function

File

Group Dimensions

Description

FfxBrixelizerGIDownsample

ffx_brixelizergi_main.h

8 x 8 x 1

Downsample input resources if using a non-native internal resolution scale.

FfxBrixelizerGIGenerateDisocclusionMask

ffx_brixelizergi_main.h

8 x 8 x 1

Generate a disocclusion mask into BrixelizerGI_DisocclusionMask.

FfxBrixelizerGIPrepareClearCache

ffx_brixelizergi_radiance_cache_update.h

1 x 1 x 1

Write indirect dispatch arguments into BrixelizerGI_RaySwapIndirectArgs for clearing radiance cache.

FfxBrixelizerGIClearCache

ffx_brixelizergi_radiance_cache_update.h

64 x 1 x 1

Clear radiance cache entries for invalidated bricks.

FfxBrixelizerGIEmitPrimaryRayRadiance

ffx_brixelizergi_radiance_cache_update.h

8 x 8 x 1

Inject reprojected radiance from the last frame into the radiance cache.

FfxBrixelizerGIPropagateSH

ffx_brixelizergi_radiance_cache_update.h

64 x 1 x 1

Propagate the SH probes at each brick into the neighboring bricks.

FfxBrixelizerGISpawnScreenProbes

ffx_brixelizergi_main.h

8 x 8 x 1

Spawn new screen probes on the depth buffer and output probe information.

FfxBrixelizerGIReprojectScreenProbes

ffx_brixelizergi_main.h

8 x 8 x 1

Reproject screen probes from the previous frame into the current frame.

FfxBrixelize.gifillScreenProbes

ffx_brixelizergi_main.h

8 x 4 x 1

Trace diffuse rays using Brixelizer to inject new radiance information into screen probes.

FfxBrixelizerGISpecularPreTrace

ffx_brixelizergi_main.h

8 x 4 x 1

Trace specular rays using Brixelizer and output brick IDs at hit points.

FfxBrixelizerGIReprojectGI

ffx_brixelizergi_main.h

8 x 8 x 1

Reproject the diffuse and specular GI outputs from the previous frame into the current frame.

FfxBrixelizerGISpecularTrace

ffx_brixelizergi_main.h

8 x 4 x 1

Resolve specular output by ray marching the bricks from the Specular Pre Trace pass and sampling the radiance cache.

FfxBrixelizerGIProjectScreenProbes

ffx_brixelizergi_main.h

8 x 8 x 1

Project the octahedral screen probes into spherical harmonics.

FfxBrixelizerGIEmitIrradianceCache

ffx_brixelizergi_main.h

8 x 8 x 1

Update the irradiance cache using spherical harmonics screen probes.

FfxBrixelizerGIInterpolateScreenProbes

ffx_brixelizergi_main.h

8 x 8 x 1

Resolve final diffuse and specular GI output and perform temporal accumulation.

FfxBrixelizerGIBlurGI

ffx_brixelizergi_main.h

8 x 8 x 1

Spatially denoise the diffuse and specular GI outputs.

FfxBrixelizerGIUpsample

ffx_brixelizergi_main.h

8 x 8 x 1

Upscale diffuse and specular GI outputs if using a non-native internal resolution scale.