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:

  1. Initial Sampling: The shader generates a small set of random candidate light sources per pixel.
  2. Temporal Reuse: The current pixel exchanges reservoirs with its corresponding pixel from the previous frame via motion vectors.
  3. Spatial Reuse: The pixel shares reservoirs with valid neighboring pixels that have similar geometric normals and depth values.
  4. 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:

  1. Path Generation: Tracing short initial indirect rays from the camera's primary hit point to find secondary bounce surfaces.
  2. Reservoir Creation: Storing the incoming radiance, hit positions, and normals of those secondary surfaces inside reservoirs.
  3. 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.
  4. 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.