Lab / Website
Lapis
A fractured lapis lazuli stone rendered in the browser, built to see how close real-time WebGL can get to an offline render.
Why I made it
I wanted to know how close a real-time web scene could get to an offline render, with no video and no baked model.
- 01The finish is in the motion: easing, timing and restraint.
- 02Performance is a design decision, so the 3D waits for a click.
- 03AI pair programming let me try far more versions than a solo schedule allows.
Built with
AI: Claude (pair programming in Claude Code)
The tools are public. The tuning isn't. Ask me how →
Part of
What it is
Lapis is an interactive 3D sculpture that runs in the browser. A single stone of lapis lazuli, deep blue with veins of pale calcite and flecks of gold pyrite, is split into about twenty fitted pieces. Move your cursor over it and the pieces nearest the pointer lift away from the stone, light leaks through the cracks, and everything eases back into place when you leave.
Around it, a field of smaller lapis stones drifts in a soft purple nebula, kept out of focus by a cinematic depth of field so the sculpture always reads first.
How I built it
About two and a half weeks, 27 September to 13 October 2026
The geometry is generated, not modelled. A seeded fracture splits a convex stone into Voronoi cells, then chamfers and chips every edge so the pieces read as broken stone rather than clean slices. Because it is seeded, the same settings always produce the same stone.
The surface is a custom shader layered on a physical material: the blue-to-navy mineral pattern, calcite veins, and pyrite flecks strung along wandering paths are all procedural, combined with a real CC0 rock texture for fine grain. The cracks glow only on their inner faces, and the glow rises as a piece opens.
The scene is built in three.js through React Three Fiber, with bloom, a patched depth of field that keeps the whole stone sharp, and a vignette in post. A tuning panel exposed every value, so the look could be adjusted live and saved as the project's defaults.
It was built in about two and a half weeks of evenings and focused sessions, with Claude as a pair programmer for the shader work, the fracture maths and the performance passes.
What I learned
Real-time can get remarkably close to offline, but only if the motion is held to the same standard as the lighting. The difference between a demo and something that feels finished was almost entirely in easing, timing and restraint.
Performance is a design decision. Generating the stone, compiling its shaders and starting the post stack all compete with the page on load, so the experiment now waits behind a launch button rather than loading on its own. A static poster carries the first impression.
And AI pair programming changes what one person can attempt. It did not decide what the stone should feel like, but it made it practical to try many more versions of the fracture and the shader than a solo schedule would normally allow.
More from the Lab
Next

