Selected work
Physics Engine · Three.jsJavaScript · HTML5 · Three.js r0.160

Marble World

Single-file rigid-body marble simulator with procedurally generated cycloid half-pipe channels, analytic sphere-capsule collision, and deep instrumentation.

A Three.js toy that simulates free rigid-body marbles falling through procedurally generated channels traced by cycloid, brachistochrone, and roulette curves. Built as a single HTML file with collision detection using analytic sphere-vs-capsule-segment geometry and a spatial hash broadphase.

Role — Solo developer
  • JavaScript (ES6)
  • Three.js r0.160
  • HTML5 Canvas
  • Web Workers (SharedArrayBuffer)
  • Chrome DevTools Protocol
  • Tailwind CSS
  • Three.js Bloom Post-processing
  • Procedural path generation

Marble World is a three.js-based physics sandbox where you tap the 3D floor to pour marbles into procedurally generated half-pipe channels. Each channel is a half-pipe traced by the parametric path of a rolling circle—cycloid, brachistochrone, or roulette—and marbles are simulated as free rigid bodies that fall, roll, slosh up the walls, and launch off the ends. Nothing is on rails; collision is handled by projecting the marble sphere onto the nearest point on each capsule segment and resolving both spatial contacts and a central basin cycloid surface via analytic math, no mesh colliders.

The physics engine uses a hybrid architecture: per-marble continuous collision detection (CCD) against static walls (each marble micro-steps its own integration in increments sized to its speed so it cannot tunnel, decoupled from the global timestep), while marble-to-marble interaction and friction run only 2× per frame. A spatial-hash broadphase, precomputed lookup table for basin profiles, and a sleep system for resting marbles optimize performance. Experimental features include position-based dynamics (XPBD) and parallel worker-thread separation via SharedArrayBuffer.

The entire codebase is embedded in a single 195 KB HTML file, including UI, Three.js rendering with bloom, and comprehensive instrumentation. A Chrome DevTools Protocol API exposes real-time profiling (per-phase timings, contact counters), deep tracing of individual marbles (recording every collision decision), and correctness tests like idempotency checks and wall-clip detection, designed to diagnose the gap between physics theory and lived experience in a dense pile at scale.

What's notable
  • Per-marble continuous collision detection that bounds the cost to each marble's speed and eliminates tunnelling at any velocity, decoupled from global timesteps
  • Analytic sphere-vs-capsule-segment collision geometry with union-of-bores broadphase and precomputed basin lookup table, replacing expensive per-frame bisections
  • Single-file architecture with inline Three.js rendering, UI controls (pattern select, world density, rain flow), and live HUD; no build step or dependencies beyond CDN Three.js
  • Deep instrumentation: Chrome DevTools Protocol API exposing per-phase timings, contact counters, single-marble tracing with every skip/contact decision, and idempotency checks to verify convergence
  • Scales from 260 to 12000 marbles (165 fps at 3000, 58 fps at 5000, 15 fps at 12000 on modern hardware)