Work
Bumpy Metaballs 2026
A rebuild of the 2013 original on WebGL2: the isosurface is polygonised on the GPU, normal-mapped without UVs and lit by an environment map, from wet flesh to glass refracting an inner core.
Three.js Conf
A physics toy for THREE.JS CONF 2026: lushly shaded procedurally generated text based on SDFs, thrown around by Ammo.js physics and sound effects produced with Web Audio API.
Flat Earth
A world map on an oblique cylindrical projection: centre it anywhere on Earth and that is the point the map gets right. Shaded relief and soft shadows over satellite imagery.
Guspira
A small reactive GUI toolkit for creative-coding sketches: every slider, tab and preset binds to a signal, so the control and the value never drift apart. No dependencies.
CCapture.js 2
A ground-up rewrite of CCapture.js: capture canvas animations at a fixed framerate, however long each frame takes to draw, and encode them to MP4 or WebM with WebCodecs. GPU motion blur and frame-accurate audio.
Inktober 2025
Thirty-one ink sketches of strange attractors and flow fields, drawn as shaded, self-shadowed MeshLine strokes.
Codevember 2022
A month of shaders and post-processing for Codevember 2022, built with WebGL and three.js.
Halloween 2022
Double Halloween feature to give some ambience to this spooky season: Pumpkin Sphere, a mass of pumpkins hovering around you; and Spooky Cloud, a particle-driven cloud of pumpkins and skulls chasing a wisp.
Floating Shiny Knot
A remake of the 2012 experiment in image-based lighting from Google Street View panoramas, now fetched with PanomNom.js, with better shading and normal mapping that perturbs the surface and its reflections and refractions.
Genuary 2022
Thirty-one days of procedural generation for Genuary 2022, with three.js and WebGL.
Codevember 2021
One experiment a day for Codevember 2021: simulations, post-processing and more with WebGL and three.js.
Web Unleashed 2021 Opening Titles
Opening titles for FITC Web Unleashed 2021: strange attractors grown into tube geometries, rendered in near real-time WebGL and captured to video.
Inktober 2021 Strange Attractor Sketches
Thirty strange attractors for Inktober 2021, drawn with the NPR hatching techniques from the 2020 sketches.
Lines on a Sphere
A refresh of Lines on a Sphere from Codevember 2016: thousands of particles tracing lines over a flow field wrapped on a sphere.
Dual Boids
A flock of spheres following classic boids rules, shaded with analytic sphere ambient occlusion based on IQ's article.
Generative art: Lines on flow fields
MeshLine strokes tracing the field lines between electrical charges. Interactive, but made for the still images it produces.
F*MMXX
An angsty new year demo to send off 2020, the year of Covid: a maneki-neko trying to beckon better fortune, lots of light effects and a lot of messages.
Generative baubles
An editor for procedural Christmas baubles: tweak the shape, materials and stripes from a panel and make your own.
SDF physics
An experiment with GPU particles bouncing off volumes defined with SDFs.
Inktober 2020 Sketch experiments
Thirty-five sketches for Inktober 2020, all NPR post-processing: hatching, cross-hatching, lines and other ink techniques. No prompts, just experimentation.
Shield VFX
A translucent energy shield: a glassy bubble patterned with Worley noise, with a glowing rim where it intersects the scene, read from the depth buffer.
Voxel Volume Rendering
Raymarching a 3D Perlin noise isosurface on the GPU, with an option to accumulate values along the ray for non-solid, cloudy volumes. It became the basis for the official three.js volume renderer.
Obsolidian
Demo for Solskogen 2020, ranked 3rd: a shape evolves through the platonic solids, from tetrahedron to sphere, down a tunnel of lights. The mesh is generated by raymarching blended SDFs. Music by gloom.
FaceMeshFaceGeometry
A three.js geometry that follows the face tracked by FaceMesh, with UVs to texture it from the video feed and anchor points to attach 3D objects to the face.
Loops 2018-2019
Around 350 loops made in 2018 and 2019 with looper, a framework for generating loops with three.js.
Digital Inktober 2019
A loop a day for Inktober 2019, made with looper and MeshLine: more complex than the year before, some of them built on strange attractors.
Capture the Flag viewer
A stylised 3D viewer for DeepMind's Capture the Flag research: matches in procedurally generated indoor and outdoor environments, where agents train and learn to interact and cooperate.
Infinite Gift
Gift boxes that lift their lids to reveal another box, which opens to reveal another, in an infinite loop. Boxes and wrapping paper are procedurally generated. Christmas Experiments 2018.
Codevember 2018
A month of loops for Codevember 2018, one a day on that day's theme, made with looper.
Digital Inktober 2018
Thirty-one loops for Inktober 2018, one a day, made with looper and drawn with MeshLine.
Explore With Me
A demo for Christmas Experiments 2017: follow the footsteps of an invisible being across the snow, steer a light that stirs the particles, and watch the spheres glow to the rhythm of the music by gloom.
Codevember 2017
Fifteen experiments for Codevember 2017, a shorter run exploring simulations and post-processing with WebGL and three.js.
WebVR Experiments: Speak To Go
A Google Creative Lab experiment that takes you anywhere in the world: say where you want to go and Google Maps, the Speech-to-Text API and WebVR put you there. Part of the WebVR Experiments launch.
Dark Haze
A Christmas Experiments collaboration: a 3D scene by cbuyukberber you can interact with a little, code with Marpi and music by gloom. Lots of ambiance with pixel texture and furry polygons.
Codevember 2016
Thirty days of experiments for Codevember 2016, with WebGL, three.js, Web Audio and procedural generation.
The Polygon Shredder
Exploration of curl noise and half-cube pseudo-instancing, using WebGL, three.js and some GLSL trickery.
THREE.MeshLine
A replacement for THREE.Line with real width, where native WebGL lines are stuck at 1px: expanded in the shader, with dashes and textured lines.
X-Mas Virus
Entry for the 2015 Christmas Experiments site. A throwback demo of neon flickering lights, made with WebGL, three.js, GLSL and Web Audio.
Día de Muertos 2015
Design your own calaca for Día de Muertos: a 3D skull you decorate with decals.
Google I/O 2015 Toy
The Google I/O 2015 logo in a room: click to throw it around. Real-time physics and analytical local ambient occlusion, made with WebGL, Web Audio API, three.js, oimo.js and Wagner.
Speech Jammer
A speech jammer to warp your reality: it plays your voice back with an adjustable delay that makes it hard to keep talking. Built with Web Audio API and WebRTC getUserMedia.
cru·ci·form
A study in architecture visualisation with models by @sejnulla. Nice music, glossy reflections, slow tracking shots, custom shading and postprocessing, using three.js and Wagner.
B E Y O N D
Real-time WebGL demo with @cabbibo for Christmas Experiments 2014. Crystal growth simulation, sound processing, custom shading and postprocessing.
It's a message in a Jack-o-lantern
Online interactive experience for Halloween, in which the user can carve a stencil into a procedurally generated pumpkin and share it.
Decals for three.js
Decals implementation for three.js, useful for temporary decorations like bullet impacts, blood splatters, burns or skid marks; or for weathering effects on objects.
SnowBox
A 3D tool to create snow thingies, though really they are snowmen: metaballs for the snow, plus carrots, buttons, bowties, hats and twigs. In collaboration with @claudioguglieri and @Sejnulla. Lots of 2D, 3D and code goodness!
Bumpy metaballs
Isosurface with Marching Cubes, bump mapping with normal mapping and triplanar mapping, shading with a MatCap shader.
Spherical Environment Mapping (MatCap/LitSphere) and Normal Mapping
Spherical Mapping (MatCap/LitSphere) with Normal Mapping, using WebGL and GLSL. This is an editor to toy around with different materials, normals and render effects. With subdivision modifier, noise and rim lighting.
NPR Sketch GLSL shader
Real-time post-processing shader to create the style of old architectural drawings.
Cross-hatching GLSL shader
Blinn-Phong shading and rim lighting. Based on the Microsoft Research "Real-Time Hatching" paper.
Shake a flake | Reactive snow
A holiday experiment with reactive snow using WebGL, Web Audio API, WebRTC and localStorage. Blow into the microphone to make the falling snow shake and twirl.
It's a Halloween Message!
Carve any message into a procedurally generated Halloween pumpkin. An experiment in procedural generation of meshes and custom shading.
Rocking Dendrites
Dendrites rocking to the music, drawn with billboard particles to fake a soft, out-of-focus depth of field. Play with the generation settings or drop in your own songs. Music by Hunz.
CCapture.js
CCapture.js is a JavaScript library to help capture animations created with HTML5 canvas at a fixed framerate.
Mars Panoramas in WebGL redux
A panorama viewer using data from Ashima Group Panorama Viewer that doubles as a Fullscreen API and Pointer Lock API experiment.
Adorable Flying Sagan
Put a coin in and Carl Sagan flies away. A quick and funny experiment with linked CSS3 transforms and animations and HTML5 audio, using the amazing art by SirMitchell and music by Shugo Tokumaru.
Latitude Reflection Mapping
First step in a series of experiments toward image-based global illumination for models using Google Street View panoramas. This is the test for an environment mapping shader that uses equirectangular panoramas.
CSS3D Clouds
An experiment on creating 3D-like clouds with CSS3 3D Transforms and a bit of JavaScript.
Conway's Game of Life in 3D
An eye-candy version of Conway's Game of Life in 3D. An experiment using WebGL with three.js to get familiar with the library.
Animated GIF in 3D
Stack the frames of an animated GIF in 3D, see the animation from every side, and twist the stack along its axis. Uses WebGL with three.js and the Drag and Drop API.
WebGL Light Box
A pure WebGL light box to show images in a web page. A rework of the previous lightbox that was built using three.js to use only the exact amount of code necessary.