All labs

Lab

Live

BlockWorld

A voxel world where the terrain and the textures are both generated.

A Minecraft-shaped technical study: how far a voxel renderer can be pushed without leaving WebGL2 and WebAssembly. A C++ chunk pipeline on a worker pool, greedy meshing, and 4×4 super-chunk batching for high view distance. No art assets — every texture is procedural.

blockworld.ciaranmccormack.com (opens in a new tab)
Draw calls at view distance 32
~2,000 → ~128
Vertices saved by greedy meshing
30 – 70%
Block edit, end to end
~2 – 3 ms
Vertex format
27 B vs 48 B naive

Generation

  • Multi-noise terrain — continentalness, peaks-and-valleys, erosion, plus a per-biome 3D cliff perturbation for overhangs
  • Ten biomes, with domain-warped temperature and moisture so borders snake instead of tracing contours
  • Rivers carved by ridge noise with elevation falloff, so they follow valleys rather than cutting through mountains
  • A three-layer cave system: cheese rooms, spaghetti tunnels, noodle worms, and rare vertical shafts
  • Separate sky-light and block-light breadth-first floods, giving an O(1) per-face brightness sample

Meshing

A greedy 2D mesher collapses adjacent faces across all six cube directions. The subtlety is ambient occlusion: per-vertex AO is baked into the merge key, so two cells only combine when their AO patterns match and the merged output stays pixel-identical to per-cell meshing.

Tile identity rides along as a per-vertex attribute; the shader looks the atlas rect up from a uniform table and wraps the texture across merged quads with fract(). No texture array, no per-vertex rect payload.

Render

  • 4×4 chunk groups merged into one BufferGeometry — the ~2,000 to ~128 draw-call win
  • Block edits patch their slot in place via partial bufferSubData rather than re-merging the group
  • Day and night driven entirely by a shared uniform scaling baked vertex light, so the cycle costs zero chunk rebuilds
  • Water animated from 32 pre-baked frames UV-scrolled by time, instead of per-frame canvas work
  • Three-tier LOD: full detail near the player, terrain-only at range, solid hills at the far edge

Stack

  • C++/WASM
  • Three.js
  • WebGL2
  • Web Workers
  • Next.js

More labs

Keep looking

  • Practice between lessons, for band kids.

    Notation and tab that plays back, listens through the microphone, and tells a kid whether they actually hit the note. Built for the gap between weekly lessons — where nearly all the practice happens and nobody is there to correct anything.

    • Next.js
    • VexFlow
    • Tone.js
    • Pitch detection
    • +1

Want the long version?

Happy to go deeper on any of this — architecture, trade-offs, what I would do differently.