How Sanctum's Clouds Work
Every formula that builds the Sanctum sky — explained in plain English, with the real math, the 3,000-year story behind it, and a live cloud you reshape with your own hands.
Every interactive cloud here is a real GPU render of the Sanctum cloud — the sliders scrub through pre-rendered frames, so it's stunning and runs on anything with no GPU needed.
Three thousand years in one strip
Not one idea in the Sanctum cloud shader is new. Each formula was cracked by someone solving a different problem — measuring starlight, painting a cathedral, photographing a landscape — long before a GPU existed. Here's the relay race.
One pixel, five steps
Every dot on your screen is a single ray fired from the camera into the world. That one ray does five things, in order. The rest of the page zooms into each — and tells you who invented it.
How a pixel becomes a ray
The camera sits at one point. Each pixel looks in a slightly different direction — centre dead ahead, edges tilting outward. How far they tilt is the field of view. One line:
The "one point → one ray" idea is ancient. Around 400 BCE the Chinese philosopher Mozi recorded that light from a person's feet enters a pinhole and lands high while light from the head lands low — so the image flips. Aristotle puzzled over why sunlight through a square hole casts a round spot (a pinhole image of the Sun). The decisive account came around 1021 from Ibn al-Haytham (Alhazen) in his Book of Optics — written, by tradition, while feigning madness to escape an impossible commission to dam the Nile. Renaissance painters then made it constructible: Brunelleschi (~1413) with a peephole-and-mirror demo, and Alberti (1435) framing the picture as "an open window." The GPU's tan(fov/2) is just Alberti's window, sized.
The sky — two colours and a sun
Before any cloud, the ray gets a sky colour: a blend between a top and a horizon colour, mixed by how high the ray points. The 4th-power curve keeps blue across the dome and crushes the pale horizon into a thin band.
(You already dragged the sun across this cloud up in the hero — that's this exact \(\mathbf{sky}=\text{mix}\big(\text{top},\text{horizon},(1-t)^4\big)\) at work.) The blend curve is what shapes it:
The colour-space bug that made everything white a real mistake
Sky colours are authored in sRGB (your monitor's space); lighting math must run in linear light. We first fed raw sRGB numbers in as if linear — and the whole scene went 60–90 luma too bright, an "ungodly bright" white-out. The fix is the sRGB→linear decode \(\left(\tfrac{c+0.055}{1.055}\right)^{2.4}\).
A cathode-ray tube never turned voltage into proportional brightness — its light rose as voltage to the power ~2.5. A nuisance, but lucky: human lightness perception is roughly the inverse of that curve, so "gamma space" also packs detail where the eye is most sensitive. In 1996 HP & Microsoft codified it as sRGB (IEC 61966-2-1, 1999). The catch: sRGB values are not light, so we linearize on read, shade, then re-encode — skip it and blends come out wrong (the white-out).
The noise library — clouds out of static
Cloud shape comes from noise — random-but-smooth patterns, sampled at different scales and stacked. Two famous noises do the work, and they fix each other's weaknesses.
Ken Perlin invented his noise around 1982–83 at MAGI while working on Disney's TRON, frustrated CGI looked too "machine-perfect." He published it in 1985 and won a 1997 Academy Award. The complement came from Steven Worley in 1996: cellular noise, built from distance to scattered points, which reads as organic. Summing octaves traces to Mandelbrot's fractals (his assistant Musgrave brought it to graphics). Decades later Andrew Schneider at Guerrilla combined them for Horizon Zero Dawn — invert Worley to erode Perlin — the exact recipe the Sanctum renderer inherits.
Density — how much cloud is here?
One function answers "how solid is the cloud at this point?" (0–1), blending the noise through a few dials. Here are the big three, each driving the real cloud.
Coverage — the master "how cloudy" dial
Sharpness & density — wispy vs firm, thin vs thick
The real cloud also uses remap (carving one shape out of another) and smoothstep (soft edges instead of hard cutoffs) — the math views:
The raymarch — sampling along the ray
We walk forward in steps, asking "how much cloud?" and adding it up. The number of steps is the quality dial — and you can see it directly:

But what is each step actually doing? Watch one ray creep in — it peeks at the cloud bit by bit and adds up what it finds:
By 1984 ray tracing had no answer for participating media — clouds, fog, smoke. James Kajiya & Brian Von Herzen (Caltech) reframed it in radiative-transfer physics: store density on a grid, step a ray through it accumulating light. In 1989 Perlin & Hoffert's "Hypertexture" made an object's shape a noise density marched in 3-D — a cloud is exactly that. In 1996 John Hart's "sphere tracing" gave the leap-by-distance trick behind Shadertoy. The Sanctum shader is the direct descendant.
Lighting — what makes a cloud look real
Where a grey blob becomes a sunlit cloud. Four pieces of physics — and you can drive the three biggest.
1 · Beer's Law — bright edges, dark cores

Absorption \(k\) — how fast cloud swallows light, the rate in \(T=e^{-kx}\). High \(k\) = dark dense cores; low \(k\) = thin and translucent. ↓ drag \(k\) on the live curve below and watch the survival rate plunge.
In 1729 Pierre Bouguer — measuring how much starlight the atmosphere swallows (he clocked the Sun at ~300,000× the Moon) — found light loss is exponential with path: equal slabs each remove the same fraction. Lambert restated it cleanly in 1760 (citing Bouguer) — so his name stuck. August Beer (1852) added that it also scales with concentration. The fairest name, "Bouguer–Lambert–Beer," is the least used.
2 · Henyey–Greenstein — the silver lining
Louis Henyey & Jesse Greenstein — two astronomers in their early 30s — published this in 1941 to model the glow of diffuse galactic light: starlight scattered by dust between the stars. Real scattering theory was too costly, so they captured the forward-peaked shape with one number, \(g\). That cheap-but-faithful trade is exactly why real-time graphics adopted it for clouds, fog, smoke and skin. The broader framework came from Chandrasekhar's Radiative Transfer (1950).
3 · The moving sun (& the warm point light)
The same sun you dragged across the cloud in the hero is its key light — low for dramatic, reddened side-lighting; high for bright noon. The sun is white; a separate orange point light at \(\hat{\mathbf{s}}=(\cos e\sin a,\ \sin e,\ \cos e\cos a)\) warms the towers from within.
Atmospherics — depth and the blue of the sky
Between you and a far cloud are kilometres of air that scatter light. The nearer-vs-farther fade is aerial perspective — and it's what gives a flat scene depth:

In 1869 John Tyndall saw a light beam through haze glow blue from the side, red from the end — but blamed dust. In 1871 Lord Rayleigh supplied the math: scattering goes as \(1/\lambda^4\), so blue scatters several times more than red (≈4× with real atmospheric numbers) — no dust needed (proven to be air molecules in 1899). Larger particles differ: Gustav Mie (1908) solved scattering off any-size spheres — forward-directed and colour-blind, which is why clouds and haze look white. The graphics lineage: Nishita (1993) → Preetham (1999) → Bruneton (2008) → Hillaire (2016).
Tonemap — squeezing HDR light into a picture
Lighting produces values past 1.0 (the sun, sunlit tops). A monitor maxes at 1.0, so naive output clips to white. The filmic curve rolls highlights off like film instead:
Exposure — how much light we feed the film curve, \(\text{out}=f_{\text{filmic}}(\text{light}\times\text{exposure})\). Push it up and a naive renderer blows the sunlit tops to flat white; the filmic curve rolls them off. ↓ drag exposure on the live curve below and watch the naive (red) line clip while the filmic (orange) one keeps detail.
In 1890 Hurter & Driffield plotted film density against the log of exposure — the S-curve with a gentle toe and shoulder, so film never abruptly clips. Reinhard (2002) brought it to digital (extending Ansel Adams's Zone System); John Hable fit a real-time version for Uncharted 2 (2010) — the curve Sanctum's tonemap descends from.
Bloom — letting the bright bits bleed
Real lenses — and your own eyes — bleed light outward from very bright areas. We copy just the bits above a brightness threshold, blur them (a Gaussian blur), and add that glow back on top:

Bloom — \(\max(\text{colour}-\text{thresh},0)\to\text{blur}\to\text{add}\). Only the bright cloud tops cross the threshold, so the glow lands on the edges without washing out the rest.
The bell curve was written by de Moivre in 1733; Gauss earned the name in 1809 from error analysis (a textbook "Stigler's Law"). Its graphics superpower is separability — a 2-D blur factorizes into a horizontal then vertical pass, \(O(k^2)\to O(k)\) — which is why it dominates GPU blurs and bloom (in games since Riven, 1997).
Animation — making the sky breathe
Each noise octave drifts with the wind at its own speed, so the clouds evolve rather than slide. Here it is in the Sanctum production sky — churning in place, and flown through:

Animation — \(\text{pos}\mathrel{+}=\text{wind}\times\text{speed}\times dt\). Each octave drifts at its own speed, so the cloud churns and evolves rather than sliding past — the schematic below shows why.
Is the real thing faithful? — the Sanctum port vs the engine
The cloud you've been dragging is no stand-in — those are real frames from the Sanctum production renderer, a full GPU raymarcher, pre-rendered so the page stays light (only the little math diagrams are drawn live in your browser). And that renderer is itself a faithful port of Bonkahe's open-source Godot shader — so to prove the port is honest, the same camera is rendered in both engines and compared on the GPU:

The whole machine, in one breath
Sky gradient → multi-octave Perlin–Worley density → coverage & remap carving → adaptive raymarch → Beer's-law self-shadow + Henyey–Greenstein rim + ambient + sun → aerial perspective → filmic tonemap → bloom → wind animation.
Every layer is one small, checkable formula — most a century or more old — stacked on the last. You just dragged every one of them.
A faithful port — and what's genuinely Sanctum's
Straight answer: the cloud recipe isn't Sanctum's to claim. It's a faithful port of Bonkahe's open-source SunshineClouds2 (Godot, MIT) — every constant matches Bonkahe's scene, checked against the real engine. That was the point: port it honestly and prove it works. What's Sanctum's is the engineering that got those clouds running — pixel-faithfully — somewhere they were never built to run:
① A compute shader, rebuilt as a web raymarch
Bonkahe's clouds are a Godot/Vulkan compute shader. The Sanctum version is a WebGL2 fragment raymarch — a genuinely different architecture (explicit textureLod, per-ray LOD-scaled marching, no implicit derivatives) to run the same math in a browser.
② Making a Vulkan shader behave on the web
Vulkan tolerates things WebGL/ANGLE don't. Sanctum found and fixed four classes of bug that turned the clouds into NaN-black on Direct3D — a reversed-edge smoothstep, a 0/0 in remap, undefined texture LOD in a divergent loop — plus the catch that ANGLE's fast-math silently eats isnan guards, so bad values must die at the source.
③ It runs on anything — no Godot
Bonkahe's version needs the Godot engine installed. The Sanctum port is a single WebGL2 page: the same clouds on a phone, in a browser, no install — which is the whole reason Sanctum, a three.js MMO heading to Steam, can actually use them.
④ Bonkahe's exact data, re-baked
Sanctum bakes Bonkahe's Godot noise resources into RGBA8 3-D volumes, so the inputs stay Bonkahe's, not an approximation. (The one real visual difference: Bonkahe animates FastNoiseLite; Sanctum marches baked Worley — same recipe, shapes land in different places.)
⑤ Proven faithful — measured, not claimed
Sanctum built a Godot ground-truth harness that renders Bonkahe's actual engine, then diffed the same camera in both on the GPU — so "faithful" is verified (that's the side-by-side just above), not a hopeful word.
⑥ Where it's heading: a living world
The port proved Bonkahe's clouds work in three.js. Next they get Sanctum's day-night sun-and-moon and world systems driving them — that integration is Sanctum's to build.
So: the cloud math is Bonkahe's, faithfully and verifiably. What Sanctum built is the bridge that makes it run as an MMO using three.js.
Sources & further reading
Every historical claim was researched against primary/reputable sources; where accounts conflict the page hedges. Highlights:
- Optics: camera obscura; Brunelleschi; Alberti, On Painting (1435).
- Scattering: Beer–Lambert (Bouguer 1729 · Lambert 1760 · Beer 1852); Rayleigh & Tyndall; Mie (1908).
- Phase & sky: Henyey–Greenstein (1941); Nishita (1993); Hillaire.
- Noise & volumetrics: Perlin (1985); Worley (1996); Kajiya & Von Herzen (1984); Hart (1996).
- Game clouds: Schneider & Vos, Nubis (2015); Bonkahe, SunshineClouds2 (MIT); Inigo Quilez, clouds.
- Tone & colour: Hable (2010); Reinhard (2002); Poynton, Gamma FAQ; sRGB.
Portrait credits — real likenesses via Wikimedia Commons / Wikipedia. Public domain: Brunelleschi, de Moivre, Lambert, Rayleigh; CC0: Alberti. Creative Commons (attribution): Mie (CC BY-SA 3.0 · ThomasHB4), Chandrasekhar (AIP Emilio Segrè Visual Archives), Mandelbrot (CC BY 2.0 · Steve Jurvetson), Ken Perlin (CC BY 2.5 · Ambuj Saxena), Nishita (CC BY 4.0). Figures with no authentic likeness — and every two-person entry — use a typeset medallion. Source links also in people-meta.json.
Built for Sanctum · the interactive sliders scrub pre-rendered frames of the real production cloud and recompute small illustrative formulas in your browser — no heavy GPU needed (see ISOLATION.md). All beauty imagery is the real GPU render.