Measuring a renderer against exact answers
· BWS · 5 min read · BYTHECLOUD ENT
Before we judge how an image looks, we check that the light in it is right — on scenes whose answer is known in closed form.
Abstract
A path tracer can look plausible and still lose or invent energy. We run the production renderer against scenes with exact answers — white furnaces for surfaces and participating media, and single scattering from a sun — and compare every result with its closed form and its statistical error. 13 of 13 checks sit inside the suite's tolerance; the diffuse sphere is the furthest from the exact answer, at 1.0096. We then follow the same renderer into a cloud, where the exact answer is replaced by a converged reference, and report how the GPU render converges to it.
Key findings
- 113 of 13 closed-form checks sit inside the suite's tolerance, across forward, isotropic and backward scattering volumes and a diffuse surface.
- 2Shadow transmittance error through a cloud fell from 0.00427 to 0.00116 after an estimator change.
- 3At 1,024 samples per pixel the GPU cloud reaches 42.4 dB against its converged render, with energy preserved.
1Why start from an exact answer
Soft light hides mistakes. A renderer that quietly loses a little energy per bounce produces images that look like a mood rather than a bug, and a cloud that is slightly too dark reads as a style. Comparing against another renderer only tells us that two programs agree. So the first check is against mathematics: scenes whose correct brightness can be written down.
01
Pick a solvable scene
A furnace or a single-scattering setup whose radiance has a closed form.
02
Render it for real
The production path tracer, with the same code path used for client work.
03
Estimate the error
Independent passes give a standard error for every measured value.
04
Compare and record
The result, the answer and the tolerance are stored together, so a regression shows up as a failed row.
2Energy in, energy out
In a white furnace every surface and every particle scatters all the light it receives, and the environment is uniformly bright. Whatever the geometry, the camera must see exactly the incoming radiance. Any darkening is energy the renderer lost; any brightening is energy it invented.
- Measured
- ± 2 standard error
- Exact answer
Axis does not start at zero
Each dot is the rendered radiance relative to the incoming light; the whisker spans two standard errors. The exact answer is one for every case.
Source: White-furnace tests · measured September 30, 2026
View data as table
| Measured | Std. error | Exact answer | |
|---|---|---|---|
| Homogeneous volume, g = 0.9 | 0.9993 | 0.0020 | 1.0000 |
| Metaball volume, g = 0.9 | 1.0018 | 0.0015 | 1.0000 |
| Metaball volume, g = 0 | 1.0000 | 0.0018 | 1.0000 |
| Metaball volume, g = −0.5 | 0.9969 | 0.0018 | 1.0000 |
| Cloud volume, dual lobe (0.85 / −0.3) | 0.9985 | 0.0012 | 1.0000 |
| Diffuse sphere, albedo 1 | 1.0096 | 0.0015 | 1.0000 |
The five volume cases sit on the answer within their error bars, including strongly forward and backward scattering. The diffuse sphere is the furthest from it, at 1.0096: inside the suite's tolerance, and the case we watch first when the surface code changes.
3Single scattering from a sun
With the sun behind the medium, light that scatters once toward the camera follows the phase function's forward lobe; with the sun behind the camera, only the backward lobe contributes. Both have exact integrals. The table compares them for three phase settings, so an error in either lobe cannot hide behind the other.
Table 1Single-scattering radiance against the exact integral
| Case | Exact | Rendered | Relative error (%) |
|---|---|---|---|
| Forward, sun behind the medium, g = 0.8 | 0.96927 | 0.97173 | +0.25 |
| Backward, sun behind the camera, g = 0.8 | 0.00241 | 0.00241 | −0.13 |
| Forward, sun behind the medium, g = 0 | 0.02154 | 0.02159 | +0.25 |
| Backward, sun behind the camera, g = 0 | 0.03906 | 0.03901 | −0.13 |
| Forward, sun behind the medium, g = −0.4 | 0.00659 | 0.00661 | +0.25 |
| Backward, sun behind the camera, g = −0.4 | 0.15190 | 0.15170 | −0.13 |
Relative error is the rendered value minus the exact value, divided by the exact value.
Source: Single-scattering tests · measured September 30, 2026
Each direction repeats the same offset for every phase setting, so it does not come from the phase function.
4Shadows through a cloud
A cloud's shadow depends on how much light survives the trip through it. We compare the renderer's transmittance with a dense numerical integral at sample points across the cloud. After an estimator change the mean absolute error fell severalfold.
0.00427
Mean absolute error, before
0.00116
Mean absolute error, after
Source: Cloud shadow transmittance · measured September 30, 2026
5How many bounces a cloud needs
Exact answers stop at simple media. For a full cumulus under a low sun we measure energy against a reference rendered with the bounce limit raised until nothing changes. Single scattering alone delivers only 20% of the light; by 64 bounces the cloud holds 94%. Clouds look bright because light bounces many times inside them, and a renderer that stops early draws them grey.
Maximum volume bounces
Energy relative to the converged reference. Bounce limits are spaced as tested, not to scale.
Source: Multiple scattering in a cumulus cloud · measured September 30, 2026
View data as table
| Maximum volume bounces | Energy |
|---|---|
| 0 | 20% |
| 1 | 27% |
| 4 | 43% |
| 16 | 72% |
| 64 | 94% |
| 512 | 100% |
6Convergence on the GPU
The same transport runs on the GPU for production renders. Against a converged reference of the same scene, peak signal-to-noise rises with samples per pixel as expected for an unbiased estimator, and the energy ratio stays at one. The side-lit shot reaches 38.2 dB at the same sample count.
- Backlit
- Side-lit
Samples per pixel
Axis does not start at zero
Two lighting setups of the same cumulus, rendered on the GPU. Higher is closer to the converged image.
Source: GPU cloud against its converged render · measured September 30, 2026
View data as table
| Samples per pixel | Backlit | Side-lit |
|---|---|---|
| 256 | 36.4 dB | 31.7 dB |
| 1,024 | 42.4 dB | 38.2 dB |