Skip to main content

Hybrid SDF GI

Hybrid SDF GI is the software global illumination technology used by XFSDK Core and XFSDK Light. It uses Unreal's global distance field, probe volumes, a surfel cache and an optional final gather; hardware ray tracing and lightmaps are not required for this documented mode.

Product-specific integration

XFSDK Core and the standalone XFSDK Hybrid SDF GI use the x_ console-variable prefix; XFSDK Light uses xl_. For the shared GI settings, only the prefix changes.

Console variable naming​

For the shared GI implementation, Core and standalone GI use x_, while Light uses xl_. The suffix, meaning and parameter values are unchanged.

XFSDK Core / Standalone GIXFSDK Light
x_gi_method=2xl_gi_method=2
x_gi_dfgi_lite_quality=1xl_gi_dfgi_lite_quality=1
x_gi_dfgi_lite_final_gather=1xl_gi_dfgi_lite_final_gather=1

Core examples below use x_. To use the same GI parameter in Light, replace that prefix with xl_. This rule does not apply to Light-only Bend screen-space shadows (xl_sss_*).

How it works​

The GI is built from four parts. Each one answers what the previous one can't.

  1. GI volumes (probes). You place volumes in the level. Each fills its box with a regular grid of probes, like NVIDIA's DDGI. Every frame, the probes that visible pixels used on the previous frame cast rays through the global distance field, and a rolling budget refreshes the rest of the volume. Each probe stores the light arriving from all directions plus how far it can see, so light does not leak through walls. Probes stuck inside geometry are moved out or switched off automatically.
  2. Surfel cache. When a probe ray hits a surface, the GI needs that surface's color and lighting. The distance field only knows shape, so The implementation places small disks (surfels) on surfaces the camera has seen, records their material and lighting from the GBuffer, and probe rays read them. This is where emissive light comes from.
  3. Per-pixel lighting. Each pixel blends the nearest probes, weighted by distance and visibility, and adds the result as indirect diffuse light. Pixels outside every volume get sky light only.
  4. Final gather (optional). Probes are 2 m apart by default, so they miss small detail: the dark gap under a rock, light bouncing off a nearby emissive object. The final gather traces one short ray per pixel to fix that up close. It follows the approach id Software presented for DOOM: The Dark Ages.

Quick start​

  1. Enable mesh distance fields and configure the GI integration required by your product; restart the editor if those project settings change. See Light configuration for Light; Core and standalone installation settings are not supplied here.
  2. Place an XFSDK GI Volume actor (Place Actors panel, search "XFSDK GI Volume") and scale its box over the playable area. Use several volumes for large or multi-room levels.
  3. Look around: probes converge over a few seconds. Use x_gi_dfgi_lite_visualize 3 to see them.
  4. Optionally press Bake GI on the volume to freeze it. See Baking.
Sky Light

Keep a Sky Light in the level. Its lighting feeds the GI's sky rays and lights pixels outside every volume. If the image looks noisy, check the Sky Light's cast shadows first: in testing it was the main source of noise, not the GI.

GI volumes​

PropertyDefaultDescription
Probe Spacing200 cmDistance between probes. Denser volumes catch smaller occluders and cost more.
Priority0Where volumes overlap, higher priority wins. Equal priority prefers the denser volume.
Blend Distance800 cmThe volume fades in over this distance from its edge, so neighbouring volumes blend smoothly.
Blend Cutoff Distance0 cmZero weight this close to the edge, before the fade starts.
Enable VolumetrueA disabled volume neither lights nor updates.
Update Priority1.0This volume's share of the probe update budget compared to other live volumes.
Probe Max Ray Distance100000 cmShorter rays are faster but miss far occluders and see more sky. Rebake after changing.
Normal Bias0.05Moves the lookup off the surface (fraction of probe spacing). Fixes self-shadowing.
View Bias0.2Moves the lookup towards the camera (fraction of probe spacing). Reduces leaks and dark bands.
Light Multiplier1.0Scales this volume's indirect light. Does not change baked data.
Update ModeBakedHow the probes stay current. See Update modes.
Update Interval4Delayed only: frames between traces of each visible probe (2–16).
Start From BaketrueResponsive and Delayed only: start from the volume's bake when it has a valid one, instead of from black.

Size limits. A volume holds up to 128 probes per axis and 262,144 probes in total. If a box needs more, the spacing widens automatically so the whole box stays covered, and the log reports the spacing actually used. Split very large areas into several volumes to keep the density you want.

Run x_gi_dfgi_lite_list_volumes to log every volume: enabled, registered, size, probe grid, update mode and bake state.

Update modes​

ModeBehaviour
ResponsiveProbes the visible pixels use are traced every frame, so moving lights and emissive objects are followed within a few frames. The rest of the volume updates on the rolling budget.
DelayedLike Responsive, but each visible probe is traced every Update Interval frames, staggered across probes. Costs 1/N as much; lighting changes fade in over up to 8 × N frames.
BakedUses the baked probes and never traces. Without a valid bake the volume runs Responsive, so it can be baked.

Volumes saved before Update Mode existed are converted on load: Use Bake If Available becomes Baked, and Keep Updating (Warm Start) becomes Responsive with Start From Bake on.

Baking​

A volume with Update Mode Baked and a valid bake stores its probes in the level and stops updating: no probe rays, no surfels. It is the cheapest way to run the GI, and the right choice for static lighting. Responsive and Delayed volumes can use their bake as a starting point (Start From Bake).

  1. Keep the editor viewport camera inside or near the volume, with x_gi_method 2.
  2. Press Bake GI on the volume (or run x_gi_dfgi_lite_bake_volumes to bake every volume that is not already frozen). Baking keeps the volume's Update Mode.
  3. Wait until the log reports the bake (LogXFSDKGI, "[GI Volume]"), then save the level.

Things to know:

  • One bake covers every quality level and the final gather. Quality and final gather work on top of the probes at runtime.
  • Probes learn material colors and emissive light from surfels, which come from what the camera has seen. Look around the volume while it bakes, especially at emissive objects, or their light will be missing from the bake.
  • A bake goes stale when the volume moves or its box or probe spacing changes; the volume then runs live until you rebake. Rebake by hand after changing lights, geometry or Probe Max Ray Distance. Clear Baked GI removes it. A frozen (Baked) volume can't be rebaked in place: clear its bake or switch it to Responsive first.
  • Bakes are stored as compact half-float binary data.

Quality​

Each level adds to the previous one.

x_gi_dfgi_lite_qualityAdds
0 LowPer-probe linear spherical harmonics. Cheapest.
1 Medium (default)Smoother probe blending, deringing, and ZH3 reconstruction for better contrast.
2 HighDistance-field cone occlusion below probe resolution (as in UE4's DFGI).
3 EpicRough specular from the probes, fading in above x_gi_dfgi_lite_specular_min_roughness (0.35).

Final gather​

x_gi_dfgi_lite_final_gather=1

Every pixel traces one short ray (3 m by default) through the distance field. The hit is shaded from last frame's screen when it is visible, otherwise from the surfels, otherwise from the GI volumes. The difference to the probe lighting is added on top, so the final gather only brings the near-field detail the probes miss, and replaces the quality 2 cone occlusion.

One ray per pixel is noisy, so it is filtered in two steps:

  1. Temporal: each pixel averages its own history (up to x_gi_dfgi_lite_final_gather_history frames), reprojected with motion vectors.
  2. Spatial: 2–5 edge-aware à-trous passes that respect depth and normals.

This is built to be stable without TAA. Areas that keep losing their history, like moving leaves, fade towards the probe GI instead of flickering.

Console variableDefaultDescription
x_gi_dfgi_lite_final_gather0Turns the final gather on.
x_gi_dfgi_lite_final_gather_distance300Ray length in cm. About one probe spacing works well.
x_gi_dfgi_lite_final_gather_rays1Rays per pixel (1–8). More rays lower noise at a linear cost.
x_gi_dfgi_lite_final_gather_history32Frames averaged at most. Higher is smoother but reacts slower.
x_gi_dfgi_lite_final_gather_filter_passes4À-trous passes (2–5). 4 passes cover 31×31 pixels.
x_gi_dfgi_lite_final_gather_confidence_samples8Samples needed for full strength. Higher is calmer on foliage.
x_gi_dfgi_lite_final_gather_screen_traces1Shade hits from last frame's screen when possible.
x_gi_dfgi_lite_final_gather_max_ray_intensity10Brightest value a single ray may return. Stops sparkles from small bright sources.

Settings​

Console variableDefaultDescription
x_gi_dfgi_lite_intensity1.0Overall indirect light intensity.
x_gi_dfgi_lite_quality1See Quality.
x_gi_dfgi_lite_probe_update_budget2048Probes retraced per frame across all live volumes, nearest first. Baked volumes never trace.
x_gi_dfgi_lite_probe_realtime_budget16384Most probes traced per frame because visible pixels used them, on top of the update budget. 0 puts every probe on the rolling budget.
x_gi_dfgi_lite_probe_realtime_interval1Minimum frames between traces of each visible probe, for every live volume. A Delayed volume's own interval applies when larger.
x_gi_dfgi_lite_probe_realtime_hysteresis0.85History kept by visible probes on each update. DDGI's rules apply on top: large changes still come through within a frame or two, and sudden jumps are limited to a quarter per update.
x_gi_dfgi_lite_surfel_drop_floating1Drops surfels left behind by moved objects: floating in front of the visible surface, or buried inside other geometry. Without it, a moved emitter keeps lighting its old place.
x_gi_dfgi_lite_sky_fallback0.5Sky light strength outside every volume. 0 leaves those pixels without indirect light.
x_gi_dfgi_lite_volume_view_distance50000Volumes further than this (cm) are ignored.
x_gi_dfgi_lite_visibility_max_distance20000Distance (cm) where the quality 2 cone occlusion has faded out.
x_gi_dfgi_lite_specular_min_roughness0.35Quality 3: roughness where probe specular starts.

Runtime GI API​

XFSDK Core, XFSDK Light, and the standalone XFSDK Hybrid SDF GI plugin expose the same runtime GI operations to Blueprint and C++.

The API selects between:

  • No dynamic global illumination
  • Unreal Engine Lumen Lite
  • XFSDK Hybrid SDF GI

Blueprint functions​

Blueprint nodeC++ functionDescription
Enable Lumen Lite GIXFSDK_EnableLumenLiteGISelects Unreal Engine Lumen and applies the Medium GI scalability level used by Lumen Lite.
Enable Hybrid SDF GIXFSDK_EnableHybridSDFGISelects XFSDK Hybrid SDF GI.
Disable GIXFSDK_DisableGIDisables dynamic global illumination.
Get GI ModeXFSDK_GetGIModeReturns the currently selected GI mode.

The three mode-selection functions return true when the complete configuration was applied. They return false when a required console variable is unavailable.

Failures are reported through the corresponding XFSDK diagnostics system as non-fatal errors.

GI modes​

The shared logical modes are:

ModeDescription
DisabledDynamic global illumination is disabled.
LumenLiteUnreal Engine Lumen is selected with sg.GlobalIlluminationQuality 1.
HybridSDFGIXFSDK Hybrid SDF GI is selected.

Lumen Lite configuration changes global illumination only. The API does not modify reflection quality.

Product integration​

The function names and behavior are shared across all three products. Module, class, and enum names differ where required by the standalone plugin.

ProductBuild.cs dependencyHeaderAPI classMode enum
XFSDK CoreXFSDK_RuntimeXFSDK_GI_API.hUXFSDKGIAPIEXFSDKGIMode
XFSDK LightXFSDK_SystemXFSDK_GI_API.hUXFSDKGIAPIEXFSDKGIMode
Standalone Hybrid SDF GIXFSDK_GI_RuntimeXFSDK_GI_Runtime_API.hUXFSDK_GI_APIEXFSDK_GI_Mode

XFSDK Core C++ usage​

Add the runtime module to the consuming module:

PrivateDependencyModuleNames.AddRange(
new string[]
{
"XFSDK_Runtime"
});

Include the API:

#include "XFSDK_GI_API.h"

Select Hybrid SDF GI:

const bool bEnabled = UXFSDKGIAPI::XFSDK_EnableHybridSDFGI();

Select Lumen Lite:

const bool bEnabled = UXFSDKGIAPI::XFSDK_EnableLumenLiteGI();

Disable dynamic GI:

UXFSDKGIAPI::XFSDK_DisableGI();

Query the selected mode:

const EXFSDKGIMode Mode = UXFSDKGIAPI::XFSDK_GetGIMode();

XFSDK Light C++ usage​

Add the system module to the consuming module:

PrivateDependencyModuleNames.AddRange(
new string[]
{
"XFSDK_System"
});

The header, class, enum, and functions are otherwise identical to XFSDK Core:

#include "XFSDK_GI_API.h"

UXFSDKGIAPI::XFSDK_EnableHybridSDFGI();

const EXFSDKGIMode Mode =
UXFSDKGIAPI::XFSDK_GetGIMode();

Standalone Hybrid SDF GI C++ usage​

The standalone plugin exposes the shared functionality from its runtime module:

PrivateDependencyModuleNames.AddRange(
new string[]
{
"XFSDK_GI_Runtime"
});

Include the standalone API header:

#include "XFSDK_GI_Runtime_API.h"

Use the standalone API class:

UXFSDK_GI_API::XFSDK_EnableHybridSDFGI();

const EXFSDK_GI_Mode Mode =
UXFSDK_GI_API::XFSDK_GetGIMode();

Select Lumen Lite or disable GI:

UXFSDK_GI_API::XFSDK_EnableLumenLiteGI();
UXFSDK_GI_API::XFSDK_DisableGI();

Blueprint usage​

The Blueprint nodes perform the same complete configuration as the C++ functions.

A typical graphics-settings flow is:

  1. Present Off, Lumen Lite, and Hybrid SDF GI to the player.
  2. Call the corresponding GI API node.
  3. Check the returned Boolean.
  4. Save the player's selected mode only when the call succeeds.
  5. Use Get GI Mode to initialize or refresh the settings UI.

Do not combine direct writes to the underlying GI method variables with the public API. Doing so may produce a configuration that no longer corresponds to one of the supported modes.

Debug views​

x_gi_dfgi_lite_visualizeShows
1Distance-field occlusion (quality 2+).
2Surfel coverage: yellow partial, green covered. Shows where probe rays find real materials.
3GI volume probes. Magenta = inactive.
4GI volume irradiance.
5Volume weights: red = live, green = baked, blue = sky fallback.
6Final gather correction: green adds light, red occludes.
7Final gather history: red = rejected this frame, white = 16+ frames.

Limitations​

  • Only geometry with mesh distance fields affects the GI. Very thin walls (below distance field resolution) can leak light; use thicker walls or denser volumes.
  • Surfels are spawned from what is on screen. Probe rays that hit surfaces the camera has not seen yet use a neutral grey (30%) material until they are seen.
  • Deferred shading only.
  • Small emissive objects light the probes through their surfels, up to 1,024 emissive surfels per frame. Emitters must have been on screen to be picked up.

References​

  • Z. Majercik, J.-P. Guertin, D. Nowrouzezahrai, M. McGuire. Dynamic Diffuse Global Illumination with Ray-Traced Irradiance Fields. JCGT, 2019. jcgt.org/published/0008/02/01
  • Z. Majercik, A. Marrs, J. Spjut, M. McGuire. Scaling Probe-Based Real-Time Dynamic Global Illumination for Production. JCGT, 2021. jcgt.org/published/0010/02/01
  • NVIDIA. RTXGI (DDGI) Unreal Engine plugin. github.com/NVIDIAGameWorks/RTXGI-DDGI
  • D. Wright. Dynamic Occlusion with Signed Distance Fields. SIGGRAPH 2015, Advances in Real-Time Rendering.
  • H. Halén, A. Brinck, K. Hayward, X. Bei. Global Illumination Based on Surfels. SIGGRAPH 2021, Advances in Real-Time Rendering (EA SEED).
  • R. Wang. SurfelPlus. github.com/WANG-Ruipeng/SurfelPlus
  • T. Roughton, P.-P. Sloan, A. Silvennoinen, M. Iwanicki, P. Shirley. ZH3: Quadratic Zonal Harmonics. Activision, I3D 2024.
  • P.-P. Sloan. Deringing Spherical Harmonics. SIGGRAPH Asia 2017 Technical Briefs.
  • T. Sousa. Fast as Hell: idTech 8 Global Illumination. SIGGRAPH 2025, Advances in Real-Time Rendering in Games (DOOM: The Dark Ages).
  • H. Dammertz, D. Sewtz, J. Hanika, H. Lensch. Edge-Avoiding À-Trous Wavelet Transform for Fast Global Illumination Filtering. HPG 2010.
  • C. Schied et al. Spatiotemporal Variance-Guided Filtering. HPG 2017.
  • D. Wright, K. Narkowicz, P. Kelly. Lumen: Real-time Global Illumination in Unreal Engine 5. SIGGRAPH 2022, Advances in Real-Time Rendering.
  • Activision. VRRT. SIGGRAPH 2026 (re-cast rays reuse their random numbers, slide 58).