{"name":"3d retro graphics","url":"https://3d-retro.com","license":"CC0-1.0","license_url":"https://creativecommons.org/publicdomain/zero/1.0/","description":"3d retro graphics is a free library of browser experiments. Each copies as a single HTML file (WebGL 1 or Canvas 2D) and is licensed CC0 1.0.","llms_txt":"https://3d-retro.com/llms.txt","llms_full":"https://3d-retro.com/llms-full.txt","openapi":"https://3d-retro.com/openapi.yaml","sitemap":"https://3d-retro.com/sitemap.xml","count":28,"experiments":[{"slug":"plasma","number":"01","title":"Plasma","era":"Demoscene · 1992","summary":"Color-field oscillator running as a fullscreen fragment shader.","description":"A demoscene plasma is a sum of sine fields in the plane, sampled through a cycling palette. This one is a single WebGL 1 fragment shader: two triangles, a time uniform, no textures. Drop the file on a page and it fills the window. Reduce motion and it holds a still frame.","apis":["WebGL 1","GLSL ES 1.0","requestAnimationFrame","matchMedia"],"tags":["shader","demoscene"],"hasGlsl":true,"interaction":null,"url":"https://3d-retro.com/experiments/plasma","example_url":"https://3d-retro.com/examples/plasma.html","api_url":"https://3d-retro.com/api/v1/experiments/plasma"},{"slug":"starfield","number":"02","title":"Retro 3d starfield","era":"Hyperspace · 1993","summary":"Perspective starfield that stretches into a hyperspace tunnel.","description":"700 points in a unit cube, projected with a 1/z divide. Depth is decremented each frame; when a star passes the camera it is recycled at the far plane. Motion blur is a cheap trail fade on the 2D canvas. Move the pointer to shift the vanishing point.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["canvas","particles"],"hasGlsl":false,"interaction":"Move the pointer over the preview to shift the vanishing point.","url":"https://3d-retro.com/experiments/starfield","example_url":"https://3d-retro.com/examples/starfield.html","api_url":"https://3d-retro.com/api/v1/experiments/starfield"},{"slug":"lowpoly","number":"03","title":"Retro torus","era":"GL workstation · 1993","summary":"Flat-shaded torus, wire overlay, and a ground grid. Drag to orbit.","description":"A torus tessellated into chunky triangles with per-face normals, lit by a mint key and a cool fill. Edges are drawn as a second line pass. A ground grid locks it to the SGI demo-reel floor. Matrix math is inline, no three.js. Drag to orbit. It auto-rotates until you take over.","apis":["WebGL 1","GLSL ES 1.0","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["webgl","3d"],"hasGlsl":true,"interaction":"Drag on the preview to orbit. Auto-rotation stops after the first drag.","url":"https://3d-retro.com/experiments/lowpoly","example_url":"https://3d-retro.com/examples/lowpoly.html","api_url":"https://3d-retro.com/api/v1/experiments/lowpoly"},{"slug":"metaballs","number":"04","title":"Chrome blobs","era":"Metaballs · 1995","summary":"Raymarched metaballs with a studio chrome environment.","description":"Three spheres blended with a polynomial smooth-min, raymarched in the fragment shader. Normals come from the gradient of the field. The material is a fake studio HDR: a horizon gradient plus two specular lights sampled along the reflected ray, with Fresnel mix. It is 1990s chrome, without a cubemap.","apis":["WebGL 1","GLSL ES 1.0","requestAnimationFrame","matchMedia"],"tags":["shader","raymarch"],"hasGlsl":true,"interaction":null,"url":"https://3d-retro.com/experiments/metaballs","example_url":"https://3d-retro.com/examples/metaballs.html","api_url":"https://3d-retro.com/api/v1/experiments/metaballs"},{"slug":"raytracer","number":"05","title":"Reflective spheres","era":"Whitted · 1980","summary":"A Whitted raytracer: three spheres, checkerboard, shadows, three bounces.","description":"Each pixel shoots a primary ray, intersects a plane and three spheres, then follows reflections for two extra bounces. Shadows are shadow rays toward a point light. The chrome ball is almost pure metal. The red and mint balls mix diffuse with a little reflection. The whole scene is one GLSL fragment shader.","apis":["WebGL 1","GLSL ES 1.0","requestAnimationFrame","matchMedia"],"tags":["shader","raytrace"],"hasGlsl":true,"interaction":null,"url":"https://3d-retro.com/experiments/raytracer","example_url":"https://3d-retro.com/examples/raytracer.html","api_url":"https://3d-retro.com/api/v1/experiments/raytracer"},{"slug":"ascii","number":"06","title":"ASCII torus","era":"donut.c · 2006","summary":"A rotating 3D torus rendered with a luminance character ramp.","description":"Andy Sloane's donut.c, drawn on a 2D canvas instead of stdout. Two nested angle loops sample a torus, project with a 1/z perspective divide, and keep a per-cell z-buffer. Lighting is a simple Lambert term mapped onto  .:-=+*#%@. Phosphor green on charcoal.","apis":["Canvas 2D","requestAnimationFrame","matchMedia"],"tags":["ascii","canvas"],"hasGlsl":false,"interaction":null,"url":"https://3d-retro.com/experiments/ascii","example_url":"https://3d-retro.com/examples/ascii.html","api_url":"https://3d-retro.com/api/v1/experiments/ascii"},{"slug":"globe","number":"07","title":"Wireframe globe","era":"IRIX · 1994","summary":"Latitude/longitude cage with a phosphor stroke. Drag to spin.","description":"A UV sphere as meridians and parallels, projected with a 1/z divide. Front edges are brighter than the far side, so the globe reads in depth without hidden-line removal. The equator and prime meridian are a touch hotter. Drag to orbit. It keeps a slow auto-spin until you take over.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["wireframe","3d"],"hasGlsl":false,"interaction":"Drag on the preview to spin the globe. Auto-rotation stops after the first drag.","url":"https://3d-retro.com/experiments/globe","example_url":"https://3d-retro.com/examples/globe.html","api_url":"https://3d-retro.com/api/v1/experiments/globe"},{"slug":"fluid","number":"08","title":"Fluid tank","era":"Stam · 1999","summary":"A stable 2D Navier-Stokes dye tank. Stir it with the pointer.","description":"Jos Stam's stable fluids on a 48x48 grid: diffuse, project (Jacobi pressure), advect. Density is a phosphor dye; velocity is splatted along the pointer stroke. An ambient vortex keeps the tank moving when nobody is stirring. The solver is the textbook Game Developer Conference version.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["sim","fluid"],"hasGlsl":false,"interaction":"Move or drag on the preview to stir the dye. A slow vortex keeps it in motion on its own.","url":"https://3d-retro.com/experiments/fluid","example_url":"https://3d-retro.com/examples/fluid.html","api_url":"https://3d-retro.com/api/v1/experiments/fluid"},{"slug":"flow","number":"09","title":"Flow field","era":"Vector field · 1996","summary":"A thousand particles following a curling field. Pointer makes a vortex.","description":"Each particle integrates a procedural vector field: sines for the ambient flow, plus a moving singularity that acts as a slow cyclone. The pointer adds a second vortex wherever it sits. Trails are a cheap canvas fade.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["particles","field"],"hasGlsl":false,"interaction":"Move the pointer over the preview to twist the field into a vortex.","url":"https://3d-retro.com/experiments/flow","example_url":"https://3d-retro.com/examples/flow.html","api_url":"https://3d-retro.com/api/v1/experiments/flow"},{"slug":"fabric","number":"10","title":"Verlet fabric","era":"Jakobsen · 2001","summary":"A hanging cloth. Drag a point to tug the weave.","description":"Thomas Jakobsen's Verlet cloth: a grid of points, distance constraints, gravity. Two corners are pinned. A slow sine is the wind. Drag any point and the rest of the mesh follows.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["sim","cloth"],"hasGlsl":false,"interaction":"Drag a point on the cloth to tug it.","url":"https://3d-retro.com/experiments/fabric","example_url":"https://3d-retro.com/examples/fabric.html","api_url":"https://3d-retro.com/api/v1/experiments/fabric"},{"slug":"terrain","number":"11","title":"Wireframe terrain","era":"Vector CRT · 1979","summary":"Scrolling vector hills. Pointer steers.","description":"A height field of summed sines, projected with a 1/z divide, stroked as a mesh that recedes into phosphor fog. The camera flies forward. Move the pointer to yaw. This is the Battlezone / Evans & Sutherland look: no textures, no hidden-line removal, just a wire landscape on a CRT.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["wireframe","3d"],"hasGlsl":false,"interaction":"Move the pointer left or right to steer.","url":"https://3d-retro.com/experiments/terrain","example_url":"https://3d-retro.com/examples/terrain.html","api_url":"https://3d-retro.com/api/v1/experiments/terrain"},{"slug":"wolfenstein","number":"12","title":"Wolfenstein raycaster","era":"id Software · 1991","summary":"A DDA raycaster. WASD to walk, pointer to look.","description":"Wolfenstein 3D's 2.5D engine: for each column, a ray steps a grid with DDA until it hits a wall, then a vertical strip is drawn at 1/distance. No polygons. Ceiling and floor are flats. A tiny map sits in the corner. It patrols the maze until you take over.","apis":["Canvas 2D","Keyboard Events","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["raycast","3d"],"hasGlsl":false,"interaction":"WASD or arrows to walk. Move the pointer to look. A/D strafe.","url":"https://3d-retro.com/experiments/wolfenstein","example_url":"https://3d-retro.com/examples/wolfenstein.html","api_url":"https://3d-retro.com/api/v1/experiments/wolfenstein"},{"slug":"voxel","number":"13","title":"Voxel Space","era":"Comanche · 1992","summary":"A heightmap ray-column renderer. Pointer steers.","description":"NovaLogic's Voxel Space: each screen column walks a height map, drawing a vertical strip whenever the terrain rises above what is already filled. Color comes from height and a cheap slope light. No polygons. The camera flies forward. Move the pointer to yaw.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["voxel","3d"],"hasGlsl":false,"interaction":"Move the pointer left or right to steer.","url":"https://3d-retro.com/experiments/voxel","example_url":"https://3d-retro.com/examples/voxel.html","api_url":"https://3d-retro.com/api/v1/experiments/voxel"},{"slug":"mode7","number":"14","title":"Mode 7 floor","era":"SNES · 1990","summary":"Affine checkerboard ground, Space Harrier style. Pointer steers.","description":"For each scanline below the horizon, a distance is recovered from camera height and the line is a slice of a 2D texture. That is Mode 7 / Space Harrier: no mesh, just a perspective divide on Y. A few pylons are billboards. Move the pointer to yaw.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["mode7","3d"],"hasGlsl":false,"interaction":"Move the pointer left or right to steer.","url":"https://3d-retro.com/experiments/mode7","example_url":"https://3d-retro.com/examples/mode7.html","api_url":"https://3d-retro.com/api/v1/experiments/mode7"},{"slug":"ps1","number":"15","title":"PS1 affine warp","era":"PlayStation · 1995","summary":"A checker cube and floor with screen-space UVs. Drag to orbit.","description":"The PlayStation interpolated texture coordinates in screen space, not 1/z. Large triangles then swim. This rasterizer does the same, and snaps vertices to integer pixels the way the GTE did. Drag to orbit. Auto-rotation stops after the first drag.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["raster","3d"],"hasGlsl":false,"interaction":"Drag on the preview to orbit. Auto-rotation stops after the first drag.","url":"https://3d-retro.com/experiments/ps1","example_url":"https://3d-retro.com/examples/ps1.html","api_url":"https://3d-retro.com/api/v1/experiments/ps1"},{"slug":"irobot","number":"16","title":"I, Robot polygons","era":"Atari · 1984","summary":"Filled cubes and pyramids, painter's algorithm. Drag to orbit.","description":"I, Robot was the first arcade game to fill polygons in real time. Faces are sorted back-to-front and painted. No z-buffer, no textures: a grid of platforms, a red tower, primary colors on black. Drag to orbit. It keeps a slow auto-spin until you take over.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["polygon","3d"],"hasGlsl":false,"interaction":"Drag on the preview to orbit. Auto-rotation stops after the first drag.","url":"https://3d-retro.com/experiments/irobot","example_url":"https://3d-retro.com/examples/irobot.html","api_url":"https://3d-retro.com/api/v1/experiments/irobot"},{"slug":"teapot","number":"17","title":"Utah teapot","era":"Newell · 1975","summary":"A Gouraud teapot. Move the pointer to drag the lights.","description":"Martin Newell's teapot, lathed and swept rather than the original 32 patches, Gouraud/Phong shaded. Two point lights sit in the scene as little orbs. Move the pointer: the key light follows, the fill stays opposite. Ceramic, lamp, and fill colors are on the tweak row.","apis":["WebGL 1","GLSL ES 1.0","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["webgl","3d"],"hasGlsl":true,"interaction":"Move the pointer to drag the two lights around the teapot.","url":"https://3d-retro.com/experiments/teapot","example_url":"https://3d-retro.com/examples/teapot.html","api_url":"https://3d-retro.com/api/v1/experiments/teapot"},{"slug":"tunnel","number":"18","title":"Dot/square tunnel","era":"Demoscene · 1991","summary":"A twisting square tunnel of dots. Pointer shifts the vanishing point.","description":"Rings recede along Z. Each ring is a square outlined with dots, corners drawn as squares. A 1/z divide is the tunnel. Twist is a spin that grows with depth. Move the pointer to drag the vanishing point.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["demoscene","3d"],"hasGlsl":false,"interaction":"Move the pointer to shift the vanishing point.","url":"https://3d-retro.com/experiments/tunnel","example_url":"https://3d-retro.com/examples/tunnel.html","api_url":"https://3d-retro.com/api/v1/experiments/tunnel"},{"slug":"fire","number":"19","title":"Palette fire","era":"Demoscene · 1993","summary":"Heat rises through a 256-color fire LUT. Pointer is a torch.","description":"The 90s fire: a low-res buffer, each pixel is the average of the three below it minus a cooling term, then a palette from black through the tweak color into yellow and white. The bottom row is random sparks. Move the pointer to poke the fire.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["demoscene","palette"],"hasGlsl":false,"interaction":"Move the pointer over the preview to feed the fire.","url":"https://3d-retro.com/experiments/fire","example_url":"https://3d-retro.com/examples/fire.html","api_url":"https://3d-retro.com/api/v1/experiments/fire"},{"slug":"scope","number":"20","title":"XY oscilloscope","era":"Vector CRT · 1970s","summary":"A Lissajous figure with phosphor persistence. Pointer changes the ratio.","description":"X is one sine, Y is another. That is the XY mode on a scope, and the picture is a Lissajous curve. Persistence is a cheap canvas fade. Move the pointer to detune the Y frequency. Ratio is the second harmonic.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["vector","crt"],"hasGlsl":false,"interaction":"Move the pointer left or right to change the frequency ratio.","url":"https://3d-retro.com/experiments/scope","example_url":"https://3d-retro.com/examples/scope.html","api_url":"https://3d-retro.com/api/v1/experiments/scope"},{"slug":"boing","number":"21","title":"Boing ball","era":"Amiga · 1984","summary":"Checkered sphere, bounce, shadow. Click to kick it.","description":"Commodore's 1984 show ball: a sphere with longitude/latitude checkers, Lambert-shaded, a flattened shadow on a perspective grid. It bounces with a little energy loss and rolls with its spin. Click to kick it.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["amiga","3d"],"hasGlsl":false,"interaction":"Click the preview to kick the ball.","url":"https://3d-retro.com/experiments/boing","example_url":"https://3d-retro.com/examples/boing.html","api_url":"https://3d-retro.com/api/v1/experiments/boing"},{"slug":"stargate","number":"22","title":"Slit-scan stargate","era":"Trumbull · 1968","summary":"A 2001 corridor from a moving slit. Pointer shifts the vanishing point.","description":"Douglas Trumbull's slit-scan: a one-dimensional strip of artwork is sampled while the camera dollies, so each pixel is a different moment. Here the slit is polar. Color streaks recede into a vanishing point. Move the pointer to shove the corridor.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["optical","3d"],"hasGlsl":false,"interaction":"Move the pointer to shift the vanishing point.","url":"https://3d-retro.com/experiments/stargate","example_url":"https://3d-retro.com/examples/stargate.html","api_url":"https://3d-retro.com/api/v1/experiments/stargate"},{"slug":"ruttetra","number":"23","title":"Rutt-Etra scan","era":"Rutt/Etra · 1973","summary":"A video raster displaced by luminance. Drag to orbit.","description":"The Rutt-Etra scan processor took a video signal and bent each scanline in Z by brightness. This one synthesizes a cheap 'video' of blobs and rings, then draws it as a wire mesh. Drag to orbit. It keeps a slow auto-spin until you take over.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["video","3d"],"hasGlsl":false,"interaction":"Drag on the preview to orbit. Auto-rotation stops after the first drag.","url":"https://3d-retro.com/experiments/ruttetra","example_url":"https://3d-retro.com/examples/ruttetra.html","api_url":"https://3d-retro.com/api/v1/experiments/ruttetra"},{"slug":"glenz","number":"24","title":"Glenz vectors","era":"Amiga · 1990","summary":"Translucent filled polygons, additive. Drag to orbit.","description":"Glenz vectors are the Amiga demo trick of drawing a solid with see-through faces so the back sides pile up as light. An icosahedron, painter-sorted, additive blend. Magenta against cyan unless you change it. Drag to orbit.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["demoscene","3d"],"hasGlsl":false,"interaction":"Drag on the preview to orbit. Auto-rotation stops after the first drag.","url":"https://3d-retro.com/experiments/glenz","example_url":"https://3d-retro.com/examples/glenz.html","api_url":"https://3d-retro.com/api/v1/experiments/glenz"},{"slug":"hopalong","number":"25","title":"Hopalong attractor","era":"Martin · 1986","summary":"A one-line iterator that fills a CRT. Pointer nudges a.","description":"Barry Martin's hopalong: x' = y − sign(x)·√|bx − c|, y' = a − x. Plot the orbit and a shape appears. Move the pointer to detune a. Color is additive phosphor.","apis":["Canvas 2D","ImageData","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["attractor","plotter"],"hasGlsl":false,"interaction":"Move the pointer left or right to change the constant a.","url":"https://3d-retro.com/experiments/hopalong","example_url":"https://3d-retro.com/examples/hopalong.html","api_url":"https://3d-retro.com/api/v1/experiments/hopalong"},{"slug":"penrose","number":"26","title":"Penrose tiling","era":"Penrose · 1974","summary":"Robinson triangles, aperiodic. Drag to pan.","description":"A pentagon of acute golden triangles, subdivided by Robinson's rule. Two rhombs, no period. Fat and thin take the two tweak colors. Drag to pan. Depth rebuilds the mesh.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame"],"tags":["tiling","geometry"],"hasGlsl":false,"interaction":"Drag on the preview to pan.","url":"https://3d-retro.com/experiments/penrose","example_url":"https://3d-retro.com/examples/penrose.html","api_url":"https://3d-retro.com/api/v1/experiments/penrose"},{"slug":"elite","number":"27","title":"Elite planet","era":"Braben · 1984","summary":"A dotted sphere and a starfield. Drag to spin.","description":"Elite's worlds were spheres of dots with the back culled, a Lambert term for the terminator, and a cheap ring. No textures. Drag to spin. It keeps a slow auto-rotate until you take over.","apis":["Canvas 2D","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["wireframe","3d"],"hasGlsl":false,"interaction":"Drag on the preview to spin the planet. Auto-rotation stops after the first drag.","url":"https://3d-retro.com/experiments/elite","example_url":"https://3d-retro.com/examples/elite.html","api_url":"https://3d-retro.com/api/v1/experiments/elite"},{"slug":"vortex","number":"28","title":"Spaghetti vortex","era":"Scientific visualization · 2026","summary":"A concentrating 3D vortex. Trails spiral in as the core slims. Illustration, not a solver.","description":"Parametric helices scaled by the 2026 OpenAI paper's leading laws: radius follows tau^(1/2), height tau^(1/2−h), with illustrative h = 0.005 and tau = 1−t/T*. Both shrink; radius shrinks faster. Drag to orbit, scrub toward T*, or follow the core with a labeled uniform zoom. Color shows normalized radius. Oscillatory corrections are omitted. Illustration of the proposed blowup construction; not a numerical reproduction of the proof.","apis":["WebGL 1","GLSL ES 1.0","Pointer Events","requestAnimationFrame","matchMedia"],"tags":["webgl","3d","particles"],"hasGlsl":true,"interaction":"Drag to orbit; auto-rotation stops after the first drag. Play, pause, scrub the approach, or follow the core.","url":"https://3d-retro.com/experiments/vortex","example_url":"https://3d-retro.com/examples/vortex.html","api_url":"https://3d-retro.com/api/v1/experiments/vortex"}]}