A pixel does not have room for a crowd.

In a path tracer, the direct-lighting question can be brutally simple:

which of these lights should I ask about?

If the scene has four lights, you can ask all of them. If it has four million emissive triangles, that plan has already failed. The renderer needs a way to look at a few candidates, keep one useful representative, and still remember how much total light the candidates stood for.

That is the quiet idea behind reservoir resampling.

It is easy to describe as a trick for picking one item from a stream. That is true, but incomplete. The useful object is not just the selected item. It is the pair:

selected sample
sum of weights seen so far

The sample gives the renderer something concrete to trace, reuse, or share. The weight sum keeps the probability story from drifting into folklore.

The Lighting Sum

Strip direct lighting down to a one-dimensional surface and a cloud of point lights. At surface position x, light i contributes

\[f_i(x)= V_i(x)\, \frac{P_i \cos\theta_i(x)}{d_i(x)^2+\epsilon}.\]

Here P_i is light power, d_i is distance, cos(theta_i) is the Lambertian geometry term, and V_i is visibility. The image value at that point is the finite sum

\[L(x)=\sum_i f_i(x).\]

The sum is small enough in the browser lab that we can compute it exactly. In a renderer, the whole problem is that the sum is too large, too dynamic, or too expensive because visibility wants shadow rays.

Monte Carlo asks for one index i from some proposal distribution q. The unbiased one-sample estimator is

\[\widehat L(x)=\frac{f_i(x)}{q_i}.\]

Uniform sampling gives every light equal chance. Power sampling gives bright lights more chance. Neither is automatically good. A bright light behind a wall is a bad sample. A weak light almost touching the surface can matter more than its emitted power suggests. The proposal is only a guess about the target.

Veach and Guibas’s multiple-importance-sampling paper is the classic rendering lesson here: difficult integrals often have several plausible sampling distributions, and robustness comes from combining them with correct weights, not from believing one proposal forever.1

Reservoir resampling is another version of the same moral. Let the proposal give you candidate lights. Score those candidates under the target you actually care about. Keep one, but keep the ledger.

The Weighted Reservoir

For a stream of candidates with nonnegative weights w_1, ..., w_M, a one-sample weighted reservoir maintains:

y = selected candidate
W = sum of weights

When a new candidate with weight w arrives:

W <- W + w
replace y with probability w / W

After the stream, candidate j is selected with probability w_j / W. Wyman’s Ray Tracing Gems II chapter gives this exact update and the induction proof for the K = 1 weighted reservoir.2 Vitter’s 1985 reservoir-sampling paper is the older streaming ancestor: choose samples in one pass when the population size may be unknown and looking back is impossible.3

For direct lighting, draw candidates i_j from a proposal q. Give each candidate the importance weight

\[w_j=\frac{f_{i_j}(x)}{q_{i_j}}.\]

Then

\[\mathbb E[w_j]=\sum_i q_i\frac{f_i(x)}{q_i}=L(x),\]

so

\[\frac{1}{M}\sum_{j=1}^M w_j\]

is an unbiased estimate of the lighting sum. The reservoir lets us also keep one representative candidate selected according to the weights, without retaining the whole candidate list.

This is the part that feels too small to matter until it becomes a GPU architecture. A pixel can stream candidates, keep one light, keep the sum, and later combine that reservoir with other reservoirs.

A Tiny Many-Light Bench

The lab below builds a synthetic many-light scene. A surface line sits at the bottom. Random lights hover above it. Thin blockers cast hard visibility occlusion. For every pixel, the code computes the exact direct-lighting sum so the Monte Carlo estimates can be graded.

The four estimators are deliberately different:

  • uniform: one uniformly chosen light;
  • power: one light sampled by emitted power;
  • RIS: M power-proposal candidates, scored by f/q, with a weighted reservoir keeping one representative;
  • temporal: the same reservoir ledger accumulated across several static frames.

The temporal curve is not a claim about free samples. It spends more candidate streams over time. The point is to make reuse visible: if the scene is static, a reservoir can carry information forward instead of starting every frame cold. If the scene moves, reuse needs validity checks and reweighting.

The audit checks finite nonnegative lighting, a weighted-reservoir selection distribution on a known stream, and Monte Carlo unbiasedness for the power and RIS estimators at the selected pixel.

With the default scene, the exact selected-pixel lighting value is 225.699. The final-frame RMSE over the 64-pixel surface is:

uniform one-light RMSE       709.707
power one-light RMSE         624.584
RIS, 6 candidates            161.132
temporal reservoir           34.034
RIS / temporal RMSE ratio      4.73x
audit                        passed

Those numbers are not universal. Move the occluders, change the power skew, or drag the selected pixel. Sometimes power sampling is already good. Sometimes it keeps proposing bright lights hidden behind blockers. The target/proposal ledger panel shows why: amber is what emitted-power sampling believes, green is what actually contributes at the selected surface point.

The important fact is not that RIS always wins. It does not. The important fact is that the estimator is auditable. The code can compare the Monte Carlo average against the exact sum because this toy scene is small. In production, you rarely get that luxury, so the estimator derivation has to carry more weight.

What ReSTIR Adds

Bitterli, Wyman, Pharr, Shirley, Lefohn, and Jarosz introduced ReSTIR for real-time ray tracing with many dynamic lights.4 Their paper combines candidate resampling with temporal and spatial reuse, derives an unbiased estimator, and also describes a biased estimator that trades some energy loss for lower noise. The headline result is not subtle: scenes with up to millions of dynamic emissive triangles rendered interactively with far fewer rays per pixel.

The lab above is smaller on purpose. It leaves out:

  • BRDF sampling and multiple importance sampling with material lobes;
  • area-light geometry;
  • shadow-ray scheduling;
  • neighbor-reservoir validity;
  • temporal rejection under motion;
  • the exact ReSTIR reservoir weight used to turn a selected sample into a contribution estimate.

What remains is the hinge: weighted reservoir sampling lets a renderer stream many candidates but carry a fixed-size state. That state is combinable. Wyman’s chapter notes that two independent reservoirs {R1, W1} and {R2, W2} can be combined by keeping R1 with probability W1/(W1+W2) and otherwise keeping R2, while the new weight sum is W1 + W2.2 That is the algebraic reason reuse is possible.

The moment reservoirs are shared across pixels, though, the target can change. A light useful for one pixel can be blocked or geometrically weak for another. The sample is portable; its weight is not automatically portable. ReSTIR’s careful reweighting is not paperwork. It is the difference between reuse and wishful thinking.

The Mental Model

I find it helpful to think of a reservoir as a receipt, not a cache.

A cache says:

here is the answer I found earlier

A reservoir says:

here is one representative sample,
and here is the measure of the candidate stream it represents

The second sentence is what makes resampling composable. Without the weight ledger, a carried light is just a lucky guess. With the ledger, it can be merged, aged, reweighted, and tested.

There is a broader software lesson hiding here. Many systems want to compress a stream into a tiny state: telemetry sketches, particle filters, online rankers, cache admission policies, progressive renderers. The failure mode is usually the same. We keep the representative object and forget the accounting that made it representative.

Reservoir resampling is a reminder that the accounting is the algorithm.

  1. Eric Veach and Leonidas J. Guibas, “Optimally Combining Sampling Techniques for Monte Carlo Rendering”, SIGGRAPH 1995. The paper frames robust rendering estimators as weighted combinations of samples from different distributions. 

  2. Chris Wyman, “Weighted Reservoir Sampling: Randomly Sampling Streams”, Chapter 22 in Ray Tracing Gems II, 2021. The chapter gives the K = 1 weighted reservoir update, discusses graphics uses, and cites ReSTIR as a reservoir-based rendering method.  2

  3. Jeffrey S. Vitter, “Random Sampling with a Reservoir”, ACM Transactions on Mathematical Software 11(1), 37-57, 1985. The paper studies one-pass sampling when N may be unknown and characterizes reservoir algorithms. 

  4. Benedikt Bitterli, Chris Wyman, Matt Pharr, Peter Shirley, Aaron Lefohn, and Wojciech Jarosz, “Spatiotemporal reservoir resampling for real-time ray tracing with dynamic direct lighting”, ACM Transactions on Graphics 39(4), 2020. The project page summarizes ReSTIR as repeated candidate resampling plus spatial and temporal reuse for many dynamic lights.