atmosphere
Fog is never switched on. It is always on, and systems lean on it.
Underwater, inside a cloud, out in space — each is a layer that pulls the fog toward its own colour and density by a weight of 0…1. The layers composite, and the result is smoothed over time. Nothing ever toggles.
Why (the "thunk")
Fog used to be snapped on at the water's surface (illustrative — NOT runnable, which is
why this block is javascript not js: the doc system SMOKE-TESTS every js example, and
this pseudocode's identifiers are all undefined):
if (underwater && !wasUnderwater) { scene.fogMode = EXP2; fogColor = blue; fogDensity = 0.12 }
That's two discontinuities in one line:
fogModechanges the shader's DEFINES, so every material is recompiled. That's a real frame hitch, not just a visual pop — the thunk you feel is mostly the compiler.- Colour and density jump instantly at the exact plane of the surface.
So: the mode is set once and never changes (it's a shader permutation), and only the uniforms — colour, density, start, end — are modulated. A layer's weight ramps over a band rather than flipping at a boundary, and a short temporal smooth mops up whatever's left.
The same mechanism handles every "you are somewhere else now" transition. It isn't three special cases; it's one:
| layer | weight ramps with |
|---|---|
| underwater | depth below the surface (over a band, not a plane) |
| cloud | approach to the blob — white before you'd ever touch the geometry |
| space | altitude leaving the atmosphere: density → 0, colour → black |
The pure part
compositeFog is a pure function — layers in, fog state out. No Babylon, no scene, so the
blending is unit-testable without an engine, which is the point: this is the code that makes
a transition feel right, and feel is worth pinning down.