ReSTIR DI and ReSTIR GI in DirectX Ray Tracing
This article provides an overview of Reservoir-based Spatio-Temporal Importance Resampling (ReSTIR) algorithms, focusing on ReSTIR Direct Illumination (DI) and ReSTIR Global Illumination (GI), and explains how they scale real-time ray-traced lighting within Microsoft DirectX Raytracing (DXR). Readers will learn the operational mechanics of both algorithms, how they solve traditional performance bottlenecks, and the technical methods used to deploy them efficiently inside modern DirectX pipelines.
Understanding ReSTIR
ReSTIR stands for Reservoir-based Spatio-Temporal Importance Resampling. In traditional real-time ray tracing, rendering scenes with complex illumination requires tracing dozens or hundreds of rays per pixel to avoid unacceptable noise. Because tracing that many rays is too expensive for interactive frame rates, standard pipelines trace only one or two rays per pixel and rely heavily on spatial-temporal denoisers, which often causes ghosting and blurriness.
ReSTIR replaces brute-force ray casting with statistical resampling. Instead of evaluating full ray paths for every light source, the algorithm generates lightweight candidate samples, evaluates their approximate contribution, and stores the most promising candidates in compact data structures called "reservoirs." These reservoirs are then shared with neighboring pixels (spatial reuse) and across consecutive frames (temporal reuse), allowing a GPU to achieve the visual fidelity of hundreds of ray samples using only a fraction of the ray budget.
What is ReSTIR DI?
ReSTIR DI focuses on direct illumination—light traveling directly from an emissive source to a visible surface. It addresses the "many-light problem," where dynamic scenes contain tens of thousands to millions of individual dynamic lights or emissive triangles.
Under ReSTIR DI:
- Initial Sampling: The shader generates a small set of random candidate light sources per pixel.
- Temporal Reuse: The current pixel exchanges reservoirs with its corresponding pixel from the previous frame via motion vectors.
- Spatial Reuse: The pixel shares reservoirs with valid neighboring pixels that have similar geometric normals and depth values.
- Final Visibility: Once the algorithm selects the single best light candidate from the resampled distribution, it casts a single shadow ray using hardware ray tracing to verify visibility.
This workflow enables scenes with millions of dynamic, un-baked lights with fully dynamic shadows, all while tracing as few as one or two shadow rays per pixel.
What is ReSTIR GI?
ReSTIR GI extends the resampling methodology to indirect illumination—light that bounces off one or more surfaces before hitting the camera. Indirect light paths are significantly harder to sample than direct light because the secondary light sources are scattered randomly across the entire 3D scene.
ReSTIR GI works by:
- Path Generation: Tracing short initial indirect rays from the camera's primary hit point to find secondary bounce surfaces.
- Reservoir Creation: Storing the incoming radiance, hit positions, and normals of those secondary surfaces inside reservoirs.
- Spatio-Temporal Shift Mapping: Reusing these indirect paths across adjacent pixels and frames through geometric shift mappings, ensuring that light arriving from complex secondary bounces remains physically plausible across different surface viewpoints.
- Validation Rays: Casting lightweight visibility rays to verify that the resampled indirect path is not occluded by newly shifted geometry.
This allows games to render multi-bounce global illumination, detailed color bleeding, and complex ambient lighting without the extreme performance penalties typically associated with real-time path tracing.
How ReSTIR DI and GI Scale Ray Tracing in DirectX
DirectX 12 exposes hardware-accelerated ray tracing through DirectX Raytracing (DXR) Tier 1.0 and Tier 1.1. ReSTIR scales ray tracing performance in DirectX through three primary mechanisms:
1. Leveraging DXR 1.1 Inline Ray Tracing (RayQuery)
ReSTIR relies heavily on compute shaders rather than traditional
ray-generation shaders. In DirectX 12, developers use DXR 1.1
RayQuery (Inline Ray Tracing) directly inside compute
shaders. This avoids the overhead of dynamic shader dispatch
(DispatchRays) and state-object switches. The GPU evaluates
candidate selection, performs temporal and spatial reservoir exchanges
via group shared memory (groupshared), and uses
RayQuery strictly for final visibility checks.
2. Ray Budget Decoupling
In standard DirectX ray tracing, performance scales linearly with the number of lights and bounces; doubling the active lights or adding indirect bounces exponentially increases ray counts. ReSTIR decouples the number of light sources from the ray budget. Whether a DirectX application features 100 lights or 1,000,000 lights, the number of ray-traversal operations executed via DXR remains fixed to the small number of final visibility checks required by the reservoirs.
3. Efficient Bandwidth and Cache Utilization
Reservoirs are lightweight 16-to-24-byte structs that store sample
weights, light identifiers, and positions. In DirectX, these structures
fit cleanly into standard structured buffers and 2D textures
(RWTexture2D). Because neighbor queries during spatial
resampling target local pixel neighborhoods, they maximize L1 and L2
cache hits on the GPU.
By shifting the computational burden from hardware ray-traversal units to standard ALU compute operations and memory reuse, ReSTIR DI and GI allow DirectX-based game engines to deliver cinematic path-traced lighting on mainstream graphics hardware.