- from_interleaved ignored its arg, so D65 came from a separate
hand-normalized table that was scaled to luminance 1 instead of
CIE_Y_integral and mapped to 300nm when it starts at 360nm. sRGB
rgb_from_xyz came out ~120x too large with the wrong white point, making
every render ~120x too bright with a colour cast. Now built as pbrt does:
from_interleaved(&CIE_ILLUM_D6500, true).
- LayeredBxDF::Tr: puts the minus on the result,
not the exponent, so transmittance was negative and grew exponentially.
killeroo-coated-gold went from 15 Infs / min -4168 / stddev 638 to clean.
- layered.rs used Float::MIN where C++ has numeric_limits<Float>::min(). Those
differ: the latter is f32::MIN_POSITIVE. Both guards were dead, leaving a
zero thickness to divide by.
- FilmBase::create expanded pixel_bounds by the filter radius. pbrt never does;
the radius widens SampleBounds() only. Output was 1372x1030, not 1368x1026.
- Gate the ENQUEUE/DEQUEUE wavefront prints behind cpu_debug; their queues
reset every depth/batch/sample so they fired constantly (100h renders).