Making Anamorph
Anamorph is a fictional single-work gallery: six hundred flat shards suspended in a white volume, meaningless from everywhere except one station, where they lock into a red circle inscribing the word FORM. The page has a single job — walk you past the lock once, and make you wait for the second pass.
Concept
The piece borrows Felice Varini's move — paint scattered across architecture that resolves from one point — and rebuilds it as live geometry. The figure is never faded, morphed or crossdissolved into place. The shards hang still; only the camera moves. The lock is the one moment the projection happens to agree with the drawing.
Palette
Argued from the gallery, not from taste: white walls, one red, and the greys a room makes by itself.
- #E9E7E2
- Gallery white — walls, air, page ground.
- #C8202F
- Varini red — the figure, the station disc, eyebrows and lock state. Lines and marks only, plus large type.
- #9A968E
- Shadow grey — hairline dial track and mid-tone debris. Never body text.
- #1E1C1A
- Wall-text ink — headings and body copy on the light ground.
- #57534C
- Derived muted ink for captions and HUD — keeps small text above 4.5:1 where the spec grey could not.
Type
Display and body. A humanist grotesk with museum-signage plainness; weight 800 tightened to −0.025em carries the wordmark and the outlined FORM ghost — the page's one moment of typographic excess.
The surveyor's voice: station labels, the Δ / θ / ALIGN readout, stat blocks. Everything measured speaks mono; everything argued speaks grotesk.
Technique
Vanilla three.js (0.160), one InstancedMesh of 600 plane instances, no textures, no post. The figure is authored flat in image-plane units — a ring of 130 tiles and four letters sampled into ~100 stroke tiles. For each tile, four rays are cast from the station through its corners. A depth t is thrown along the centre ray, the first corner is displaced to t(1+ε), and the remaining three depths are recovered from a 3×3 linear solve so the four corners form a genuine tilted parallelogram still riding all four rays — the one-parameter family of planes that project exactly to the original rectangle. Each solution becomes an instance basis matrix, so the anamorphosis is exact by construction: a verification hook reprojects all ~940 corners at runtime and reports a residual around 10⁻¹⁵ units.
The camera walks a closed centripetal Catmull-Rom loop whose first control point is the station. Time is choreographed in three segments — a 12 s drift through the debris, a 13 s approach easing in-out-cubic so velocity dies exactly at the lock, then a 1.8 s dwell at the exact pose — and orientation is a quaternion slerp from the walking gaze to the lock gaze, weighted by a bump that reaches 1 only at the station. Cursor parallax lets you lean off the path everywhere except near the lock, where its gain is scaled to zero: the viewpoint is not negotiable.
Housekeeping: shards that would pierce the floor get per-ray depth caps; a cone around the sight line is kept free of grey debris; the floor grid fades to the background colour before the figure zone so nothing hangs below a visible plane. DPR capped at 2, rAF paused on document.hidden, reduced motion renders the locked viewpoint as a settled frame, and context loss swaps in an inline-SVG plate of the resolved figure built from the same stroke data.
Iteration log
-
PASS 1 · CRAFT
Drove the loop through the lock and asserted the signature: pose error 0, projection residual ~10⁻¹⁵, 600 instances — 235 figure shards, 365 debris. Found the approach reading too resolved too early — eased the second segment from quart to cubic so shear is still visibly closing at the 7-second mark. Rebalanced HUD contrast: readout numerals moved from shadow grey to wall ink, dial track kept grey. Tightened hero tag measure to 32ch and gave the wordmark its red-ring full stop.
-
PASS 2 · DEPTH
Enriched the shard population with tilt tiers — 70% shallow, 25% steep, 5% near-edge-on ribbons whose corner depths spread over a metre — so the off-lock cloud reads as wreckage rather than confetti. Added the second-read details: the red station disc on the floor at the exact lock coordinates, the pass counter that increments every loop, and the far-wall hesitation at s=0.5 where the walk pauses inside the debris before turning home. Cursor-lean micro-interaction gated by the lock weight.
-
PASS 3 · HARDENING
375px: HUD Δ/θ rows collapse to the ALIGN line, hero copy reserves right padding so the dial never overlaps, and the lock stays fully framed by widening the field of view from the same station — position, not fov, is what the anamorphosis depends on. A portrait screenshot then caught the resolved ring's lower band crossing the red eyebrow, red on red; fixed with a portrait view-offset that slides the projection window down so the figure rides higher in frame — same pinhole, shifted crop, geometry untouched. Verified reduced-motion settles on the locked frame, context-loss shows the SVG plate, focus rings on all links, zero console errors headless, and two screenshots 1.3 s apart differ. Driving the loop headless asserted the signature: pose error 0 at the station, projection residual ~10⁻¹⁵, the 1.8 s hold beat counting, and parallax error climbing past twelve metres mid-loop. Chanel rule: removed a planned centre-screen reticle that crowded the resolved figure — the corner dial carries the alignment story alone.