Turning an integral into a sum
Step size, banding, and the noise that fixes it
The volume rendering equation integrates continuously along the ray. A computer cannot, so it samples — and every sample is a rectangle standing in for a slice of the true curve. Too few and the rectangles are visibly wrong, in a way that shows up on screen as structure that is not in the volume — banding in a smooth medium, a lattice of false detail in a textured one. The standard fix is not more samples but worse‑placed ones.
—
Every ray starting at the same offset makes the same mistake at the same depth, and neighbouring pixels make it in lockstep. Correlated error is what the eye reads as pattern — a false contour across a smooth gradient, or the regular lattice on the left.
Offsetting each ray by a random fraction of a step does not reduce the error at all. It decorrelates it, so the identical amount of wrongness arrives as high‑frequency noise instead of structure. The eye forgives noise and cannot forgive contours, and a temporal or spatial blur mops up what is left. Tick the box and watch that pattern dissolve into speckle without adding a single sample.
Each rectangle is one map() call standing in for a whole slice of the ray. Where the curve moves quickly inside a single rectangle, that sample is guessing.
Solid is the reference; the stepped line is your sum. Notice that the error is not random — a coarse sum consistently overshoots in some places and undershoots in others, and that bias is what a band is made of.
σt·Δt > 0.3 or so, which the fourth readout is measuring for you. That gives a usable design rule: the step size you need is set by the densest part of the volume, not by its size. Doubling the resolution of your volume texture does not change this; doubling the density does. It is also the argument for adaptive step sizes, where the marcher takes long strides through empty space and short ones inside the cloud — the volumetric cousin of what sphere tracing does automatically for surfaces.