Task 5 of 5

The Noise Falls Like 1/√n

You have watched the noise go. Now measure it, because the rate it goes at is the single most important number in rendering — and it is the same 1/√n that Monte Carlo Methods derives for a dart-throwing estimate of π. A path tracer is that estimator with a much more interesting integrand.

Measuring it needs a reference, and the honest trick is to build one out of thin air: run the accumulation twice, with two different slices of the random stream. Neither run is the truth, but their errors are independent, so the RMS gap between them is √2 times either one's own error. Halve the square and you have measured your own noise with no ground truth anywhere in sight.

Plot that against errs[0] / √n on a log axis. If the two curves lie on top of each other, the estimator is behaving exactly as theory says — and the shape of them is the bad news in the theory: halving the noise costs four times the samples. That single fact is why production renderers spend their effort on importance sampling and denoisers instead of simply waiting longer.

Goal: finish sqDiff — half the squared difference between the two runs at this pixel — and build the 1/√n reference curve to plot against it.

Requirements

Hint 1 — where the half comes from

Run A is off by eₐ and run B by e_b, independently. The gap between them has variance var(eₐ) + var(e_b) = twice one run's. So the square of the gap, halved, estimates the square of one run's error — and the square root of the mean of that is the RMS error you want.

Hint 2 — the kernel
const d = a[this.thread.y][this.thread.x] - b[this.thread.y][this.thread.x];
return 0.5 * d * d;

Squaring in the kernel and square-rooting once in JavaScript is the usual split: the per-pixel work is parallel, the final scalar is not.

Hint 3 — the reference curve

Anchor it to the measurement you already have, so the two lines start together and any drift between them is real:

ideal.push(errs[0] / Math.sqrt(f + 1));

Same idea elsewhere

√n is why every serious renderer stopped brute-forcing: importance sampling, next-event estimation and multiple importance sampling all attack the constant in front of the 1/√n because the exponent itself cannot be moved; low-discrepancy (quasi-Monte Carlo) sequences buy a slightly better exponent on smooth integrands; and OptiX's and OIDN's neural denoisers give up unbiasedness altogether to get the picture twenty times sooner. The measurement you just made — two independent runs, no reference image — is also how those denoisers are evaluated in practice.

All tasks in Progressive Path Tracing: Noise Melting Into an Image

  1. Dice Every Thread Can Roll
  2. Where the Ray Hits
  3. One Path Per Pixel, and It Looks Terrible
  4. The Buffer That Outlives the Frame
  5. The Noise Falls Like 1/√n

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.