Inspiration

The brief said technical difficulty was not the goal — the goal was the most memorable experience possible. So we went looking for something that only works in 3D and cannot be faked in 2D.

Multi-view anamorphic sculpture is that thing. One fixed cloud of fragments, three marked viewpoints, three completely different recognizable shapes. Nothing moves, nothing morphs, nothing is projected onto anything. The reveal needs no narration: you see a bird, you drag sideways, it falls apart into a constellation, and a key assembles out of the same untouched geometry.

What it does

Passage is a gallery of three such sculptures. You orbit freely; when you arrive at one of the three marked observation stations the camera settles into an orthographic view and the silhouette snaps into legibility. Between stations the illusion breaks apart into a spatial field of luminous fragments, which is the honest and much prettier state.

You can move the key light, switch sculptures, and read a live telemetry strip showing fragment count, grid resolution and carve time.

You can also draw your own. Three small canvases, one per axis. Draw a shape on each, press carve, and the same solver builds a sculpture from your masks and scores how well it actually reads.

How we built it

The core is voxel carving — a visual-hull intersection.

  1. Three silhouette masks are rasterised to binary bitmaps.
  2. A 128 x 128 x 128 voxel grid is walked. A voxel survives only if its projection along Z lands inside mask A, its projection along X lands inside mask B, and its projection along Y lands inside mask C.
  3. That intersection is the sculpture. It is the largest set of points that can possibly satisfy all three silhouettes at once.
  4. The surviving set is thinned with a boundary-preferring subsample so the result reads as a sparkling fragment field rather than a solid block, and rendered as an additive-blended instanced mesh.

Orthographic projection at the stations is not a style choice — it is required. Under perspective the projection is not a parallel cast and the silhouettes do not resolve, so the camera blends from a perspective orbit rig into an orthographic one as it settles.

Carving runs in a Web Worker and lands in single-digit milliseconds, which is what makes the draw-your-own mode feel instant.

Built with three.js and WebGL2, vendored locally. Static files, no build step, no runtime CDN, no backend.

Challenges we ran into

Getting the silhouettes to actually read. A visual hull is the maximal consistent set, so it can only ever be a superset that still projects inside every mask — but if the three shapes disagree badly, the intersection collapses to something thin and unreadable. Shapes with a lot of interior area intersect well; spindly shapes with long thin limbs do not. Several attractive mask trios were thrown out for this.

The second challenge was proving the illusion instead of asserting it, which is where the IoU readout came from.

Accomplishments we're proud of

  • Three working scenes, roughly 28,000 fragments each, carved on a 128³ grid in single-digit milliseconds.
  • The app measures its own illusion: it re-projects the carved voxels back onto each mask and reports intersection-over-union per station live. Across the three scenes those land between 0.64 and 0.98.
  • Draw-your-own runs the identical solver and scores user masks the same way, so it cannot flatter itself.
  • Zero console errors, zero network requests after load.

Honest limits

IoU is not uniform. The strongest station on scene one reads 0.99 while the weakest reads 0.72, which is the visual hull being honest: some silhouettes are simply harder to satisfy simultaneously than others. We show the per-station number rather than an average precisely because the average would hide that.

The carve is a hard binary intersection with no anti-aliasing on mask edges, so very fine detail in a drawn mask is lost at 128³. And the three scenes are authored, not generated — the generator is the draw-your-own path, and its results are only as good as what you draw.

What we learned

The interesting engineering was not the rendering, it was the camera. An illusion that depends on projection geometry forces you to be exact about the projection, and the moment we stopped treating the camera as decoration and started treating it as part of the solver, the whole thing clicked.

What's next

Higher grid resolution with a sparse octree, soft-edged masks so drawn shapes survive better, four- and five-view sculptures (they get dramatically harder), and a shareable permalink that encodes the three masks in the URL.

Built With

Share this project:

Updates