Skip to main content

Measuring a renderer against exact answers

BWS5 min readBYTHECLOUD 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

  1. 113 of 13 closed-form checks sit inside the suite's tolerance, across forward, isotropic and backward scattering volumes and a diffuse surface.
  2. 2Shadow transmittance error through a cloud fell from 0.00427 to 0.00116 after an estimator change.
  3. 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.

Diagram 1How each check runs
  1. 01

    Pick a solvable scene

    A furnace or a single-scattering setup whose radiance has a closed form.

  2. 02

    Render it for real

    The production path tracer, with the same code path used for client work.

  3. 03

    Estimate the error

    Independent passes give a standard error for every measured value.

  4. 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.

Figure 1White-furnace radiance against the exact answer
  • Measured
  • ± 2 standard error
  • Exact answer
Homogeneous volume, g = 0.9
0.9993 ± 0.0040
Metaball volume, g = 0.9
1.0018 ± 0.0030
Metaball volume, g = 0
1.0000 ± 0.0036
Metaball volume, g = −0.5
0.9969 ± 0.0036
Cloud volume, dual lobe (0.85 / −0.3)
0.9985 ± 0.0024
Diffuse sphere, albedo 1
1.0096 ± 0.0030

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
MeasuredStd. errorExact answer
Homogeneous volume, g = 0.90.99930.00201.0000
Metaball volume, g = 0.91.00180.00151.0000
Metaball volume, g = 01.00000.00181.0000
Metaball volume, g = −0.50.99690.00181.0000
Cloud volume, dual lobe (0.85 / −0.3)0.99850.00121.0000
Diffuse sphere, albedo 11.00960.00151.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

CaseExactRenderedRelative error (%)
Forward, sun behind the medium, g = 0.80.969270.97173+0.25
Backward, sun behind the camera, g = 0.80.002410.00241−0.13
Forward, sun behind the medium, g = 00.021540.02159+0.25
Backward, sun behind the camera, g = 00.039060.03901−0.13
Forward, sun behind the medium, g = −0.40.006590.00661+0.25
Backward, sun behind the camera, g = −0.40.151900.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.

Figure 2Cloud energy by maximum number of volume bounces
0255075100%
100%
0141664512

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 bouncesEnergy
020%
127%
443%
1672%
6494%
512100%

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.

Figure 3Peak signal-to-noise against the converged render
  • Backlit
  • Side-lit
30354045 dB
42.4 dB38.2 dB
2565121,024

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 pixelBacklitSide-lit
25636.4 dB31.7 dB
1,02442.4 dB38.2 dB

Data sources

DatasetMeasured
Renderer exactness suite, summarySeptember 30, 2026
White-furnace testsSeptember 30, 2026
Single-scattering testsSeptember 30, 2026
Cloud shadow transmittanceSeptember 30, 2026
Multiple scattering in a cumulus cloudSeptember 30, 2026
GPU cloud against its converged renderSeptember 30, 2026

Published with BWS

More from Research

  1. StorMStorM Web Engine: what loads up frontCompressed size of the code StorM Web Engine loads up front, as a site ships it, and the budget it is held to.
  2. StorMResearch for people, not instead of themWhat symbiosis means in our work, and where you can already see it.