The Classic: Spinning ASCII Donut
Based on Andy Sloane's famous "donut.c" — a parametric torus rendered in real-time with 3D rotation matrices, z-buffering, and luminance-based character mapping.
Parametric torus → 3D rotation → perspective projection → z-buffer → luminance → character
Wireframe ASCII Cube
A 3D cube rendered with wireframe lines. Vertices are rotated in 3D space, projected to 2D, and edges are drawn using Bresenham's line algorithm on a character grid.
ASCII Sphere with Dynamic Lighting
A sphere rendered with surface normal calculations and luminance-based character mapping. The light source rotates around the sphere, creating dynamic shading in real-time.
Character Density Map
Surface normal · light = luminance → character lookup
ASCII Terrain Landscape
A procedural 3D terrain generated with sine wave height maps, viewed from above. The terrain scrolls continuously, with height values mapped to character density.
ASCII Art Gallery
Static 3D ASCII compositions exploring depth, perspective, and spatial illusion.
3D Text Extrusion
_____ ____
|__ // __ \
/ // / / /
/ // /_/ /
/____\____/
___/ /___
|___//___/
/_/ Isometric Room
╔═══════════════╗
╱║ ║╲
╱ ║ ROOM 3D ║ ╲
╱ ║ ║ ╲
╱ ║ ║ ╲
╱ ╚═══════════════╝ ╲
╱ ╱ ╲ ╲
╱____╱___________________╲____╲
║ ╱ ╲ ║
║ ╱ ╲ ║
║ ╱ ╲ ║
║╱___________________________╲║Perspective Tunnel
╔═══════════════════════════════╗ ║███ ███║ ║██ ██║ ║█ █║ ║ ║ ║ ╔═══════════════════╗ ║ ║ ║ ║ ║ ║ ║ ╔═════════╗ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╔═╗ ║ ║ ║ ║ ║ ║ ║·║ ║ ║ ║ ║ ║ ║ ╚═╝ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╚═════════╝ ║ ║ ║ ║ ║ ║ ║ ╚═══════════════════╝ ║ ║ ║ ║█ █║ ║██ ██║ ║███ ███║ ╚═══════════════════════════════╝
Ascending Stairs
___
___| |
___| |
___| |
___| |
|
┌────────────────┤
│ ┌───┤
│ ┌───┤ │
│ ┌───┤ │ │
│┌───┤ │ │ │
││ │ │ │ │How 3D-to-ASCII Rendering Works
1. 3D Mathematics
Define 3D geometry using parametric equations (torus, sphere) or vertex coordinates (cube).
// Torus surface point x = (R2 + R1·cos(θ)) · cos(φ) y = (R2 + R1·cos(θ)) · sin(φ) z = R1 · sin(θ)
2. Rotation
Apply rotation matrices to transform points in 3D space around X, Y, and Z axes.
// Rotate around Y-axis x' = x·cos(θ) + z·sin(θ) z' = -x·sin(θ) + z·cos(θ)
3. Projection
Project 3D coordinates to 2D screen space using perspective division (divide by Z).
// Perspective projection screenX = (K · x) / z screenY = (K · y) / z
4. Z-Buffering
Track depth for each pixel to determine which surfaces are visible (closer surfaces obscure farther ones).
if (1/z > zbuffer[x,y]) {
zbuffer[x,y] = 1/z
draw_pixel(x, y)
}5. Surface Normals
Calculate the normal vector (perpendicular) for each surface point to determine how it faces light.
// Normal for parametric surface N = ∂P/∂u × ∂P/∂v normalize(N)
6. Luminance
Compute brightness using the dot product between surface normal and light direction.
// Lambertian shading L = N · lightDir L = max(0, L)
7. Character Mapping
Map luminance values to characters based on visual density. Bright = dense (@, #), dark = sparse (., ␣).
chars = " .,:;=+*#%@" idx = floor(L · chars.length) char = chars[idx]
8. Output
Render the 2D character buffer to a <pre> element with monospace font and proper line-height.
// Character ramp (light→dark) " .,-~:;=!*#$@" or " .,:;=+*#%@"
The Demoscene Heritage
ASCII art rendering has deep roots in demoscene culture — the underground computer art movement focused on creating audiovisual demonstrations under extreme constraints. 3D ASCII art showcases the beauty of limitations: expressing complex 3D graphics within a fixed-width text grid, often in tiny file sizes. The famous "donut.c" by Andy Sloane is just 1KB of code yet renders a fully shaded, rotating 3D torus in real-time.
Classic terminal palettes: Green on black (#00ff41 / #0a0a0a), amber on black (#ffb000 / #0a0a0a), white on black (#e0e0e0 / #0a0a0a).