Builtin Library
README.md
skyResponse.module
A probe volume's sky term, evaluated at publish time instead of baked in.
A probe bake follows each path until it escapes, and what escapes carries the sky's colour. Baking that in fixes the sky the moment the bake finishes: a scene cannot dim its sky for dusk, or clear an overcast, without paying for the bake again.
The sky enters the path integral as throughput * sky where a ray escapes, and
throughput — the product of the albedos the path already passed through —
does not depend on the sky. So the field splits exactly, per channel:
field(sky) = lights + sky * aperture
lights is a bake under no sky. aperture is what a unit sky adds: how much of
it each probe can see, tinted by whatever the light passed through on the way,
so sky arriving through a red wall stays red.
local skyResponse = require("@builtin::systems.globalIllumination.skyResponse")
skyResponse.calibrate(volId) -- two bakes, once
skyResponse.apply(volId, { 0.3, 0.6, 0.9 }) -- no bake
combine(lights, aperture, sky) is the evaluation itself and is pure, so what
a sky colour does to a field can be checked without a volume or a GPU.
calibrated / terms / clear manage what a volume holds.
Why the split is exact
Both terms come from real bakes at the same settings, and the bake seeds each path from the probe and sample index alone — no clock, no frame counter. Two runs therefore trace the same paths, and the subtraction that isolates the aperture carries no sampling residual: it is the difference of two identical path sets, not of two noise realisations.
Each coefficient's fourth lane carries the probe's per-axis visibility reach
rather than light. No sky changes geometry, so that lane is carried from the
lights term and never differenced.