Pixels Can Keep One Light
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
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
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
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
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:Mpower-proposal candidates, scored byf/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.
-
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. ↩
-
Chris Wyman, “Weighted Reservoir Sampling: Randomly Sampling Streams”, Chapter 22 in Ray Tracing Gems II, 2021. The chapter gives the
K = 1weighted reservoir update, discusses graphics uses, and cites ReSTIR as a reservoir-based rendering method. ↩ ↩2 -
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
Nmay be unknown and characterizes reservoir algorithms. ↩ -
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. ↩