KEPLER·1611

Build notes · Nº 194 · Form

How Kepler
was made

One page, one job: make the densest sphere packing in the universe feel inevitable — by pouring twenty-five thousand spheres into two crates and letting the readouts argue.

Concept

Kepler is a monument to a theorem that started at a market stall. A glass crate fills with steel spheres that settle into face-centred cubic layers while a density readout climbs and locks at π/√18 = 0.7405; beside it, an identical crate takes the same spheres dumped at random and jams near 0.57 — the whole 387-year argument staged as a split view. The audience is anyone who has ever stacked oranges; the page's single job is to make the number 0.7405 feel earned, not asserted.

Palette

#131519
arsenal-night — the cannonball yard after dark; lets steel and copper carry all the light
#8B95A4
sphere-steel — the material of the subject; 25,000 instances of it
#C87550
copper mark — reserved for the winning number, the stacking plane and the marks; never body copy
#E5E8ED
gunmetal-ink — headings and emphasis at 15:1 on the night ground
#98A1AF
derived body-ink — steel demoted to lines and marks was too dim for copy; this reads at 7:1

Type

Libre Franklin at weight 900 carries the display — a hard-working American grotesque with the confidence of a munitions stencil, set tight and uppercase for the wordmark. Sometype Mono does everything numeric: the live density digits in tabular figures, plane labels, eyebrows and the league table — because the entire argument of the page is a number, and numbers deserve a face built for them.

Techniques

Vanilla three.js, two InstancedMesh crates, no physics engine. The lattice is honest: layer L sits at height r + L·√(8/3), a honeycomb offset through the A-B-C positions of close packing — that construction is face-centred cubic. The pour is choreographed descent onto those precomputed targets, bottom layers first, radial sweep within each layer, with an ease-in fall and a copper impact pulse on landing. The top third fills on a decaying long-tail schedule so the crate is still trickling minutes in.

The readout is measured, not scripted: a counting box aligned to whole lattice periods (half-open windows — 16r × 8√3·r × 12 layer heights) counts settled centres each tick; density is N·(4πr³/3) / V. When the box region completes, N hits exactly 8×8×12 = 768 and the display locks at 0.7405 because the mathematics does, not because a tween finishes. The rival crate is a sequential drop-and-roll deposition: each sphere drops at a random (x, z), rests on its highest contact, then rolls downhill across the pile's support surface — descending steps with a halving stride — until it sits in a true local minimum, almost always three contacts. Measured by the same window method it lands at 0.57, where loose random pours land. The stacking-plane highlight retints one real layer of instances copper every 2.6 s and labels it A, B or C from layer mod 3.

Iteration log

PASS 1
CRAFT

The portrait camera fitted both crates horizontally, shrinking them to toys on a phone — reframed narrow viewports as a diagonal composition, near crate at 70% width, rival crate behind in the fog. Demoted sphere-steel from body copy to lines and marks and derived a proper body-ink (#98A1AF, 7:1). Readout cards got tabular numerals, a scrim and a blur; their footnotes hide at 640px where they crowded the digits.

PASS 2
DEPTH

Landing spheres now flash copper for 220 ms, so the pour reads as impacts rather than teleports. Seeded 1-in-350 copper spheres through the steel — the bruised apples in the crate. Every ~40 s one sphere misses the crate entirely, bounces off the yard floor and rolls away — the second-read detail. Hovering or focusing the crate readout reveals the full 0.74048049; pointer parallax added at ±7 units, reduced-motion excluded.

PASS 3
HARDEN

Headless drive-testing caught three honest-numbers bugs. The counting box's top layer sat on the slow trickle schedule, so the readout could never lock during the intro — the fast fill now covers every boxed layer and the census completes about 4.5 s in. The sack pour rested spheres on single contacts — a ballistic deposit measuring 0.30, not a pour — and was rebuilt to roll each sphere to a genuine three-contact local minimum, landing at 0.57. And the HUD tick was overwriting the hover-revealed full digits. The sim clock clamp is now generous (0.3 s) so slow devices stay wall-clock honest rather than slipping into slow motion. Verified: readout locks at exactly 0.7405 with N = 768/768, plane letters cycle A→B→C, 375px clean, reduced-motion renders the settled crystal with locked readouts and no loop, WebGL context loss swaps to the static fallback.

Links

Back to the crate · Generative Assets index