3D Terminal Rendering Magic
Donut.c on steroids — A full 3D engine in your terminal
@@@@@
@@@@@@@@
@@@@@@@@@@
@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@
=============================================
*** MERRY CHRISTMAS *** HO HO HO ***
=============================================
Three distinct 3D surfaces: a curved cone (hat body), torus (fluffy rim), and sphere (pom-pom), all mathematically defined.
Two-axis rotation using X and Y rotation matrices for smooth 3D spinning animation.
Perspective projection using inverse depth—the same trick from the classic donut.c renderer.
Depth buffer ensures closer points override farther ones for proper 3D occlusion.
Normal vectors dotted with light direction determine ASCII character brightness.
Red hat body, white pom-pom and rim, yellow scrolling text—all in glorious terminal colors.
Where Sₓ = 55 and Sᵧ = 30 control the scale
Higher luminance values map to brighter characters
def plot_pixel(x, y, z, color, luminance):
# Rotate around X-axis
y2 = y * cosA - z * sinA
z2 = y * sinA + z * cosA
# Rotate around Y-axis
x3 = x * cosB - z2 * sinB
y3 = y2
z3 = x * sinB + z2 * cosB
z3 += 6.0 # Move in front of camera
# Perspective projection
ooz = 1 / z3
xp = int(WIDTH / 2 + 55 * ooz * x3)
yp = int((HEIGHT / 2 + 2) - 30 * ooz * y3)
# Z-buffer test
idx = xp + yp * WIDTH
if ooz > zbuffer[idx]:
zbuffer[idx] = ooz
# Map luminance to ASCII
char = chars[int(luminance * 8)]
output[idx] = color + char + RESET
80×30 characters × ~100 points per shape × 3 shapes = Beautiful 3D ASCII art
This project is a love letter to a1k0n's donut.c
Taking the same mathematical principles and pushing them further:
✓ Multiple complex geometries
✓ ANSI color support
✓ Scrolling text billboard
✓ More sophisticated shading
"Sometimes the best way to understand something
is to rebuild it from scratch and make it your own."