atanor
Motor 3D ray-traced que vive solo y exclusivamente en la terminal. Sin GPU,
sin ventana gráfica, sin un solo píxel fuera del emulador. Cada celda son dos
medios-bloques Unicode (▀ con fg/bg distintos), y cada uno de esos
sub-píxeles sale de un rayo trazado contra la escena.
terminal cell ┌── pixel superior (fg)
┌─────┐ │
│ ▀ │ = ▄ + ▀ ────┤
└─────┘ │
└── pixel inferior (bg)
Quickstart
Necesitas Rust estable (≥ 1.75 deberían bastar).
cargo run --release
La primera build tarda — descarga glam, crossterm, ratatui y rayon.
Lánzalo en un terminal con soporte truecolor (kitty, alacritty, wezterm,
ghostty, foot, iTerm2…). La resolución efectiva la decide el tamaño de la
ventana.
Controles
| Tecla | Acción |
|---|---|
W / S |
Avanzar / retroceder |
A / D |
Strafe izquierda / derecha |
Q / E |
Bajar / subir |
| flechas | Mirar (yaw + pitch) |
Shift + ↑ |
Sprint — 3.5× velocidad de movimiento y de look |
[ / ] |
Bajar / subir samples/pixel (SSAA) |
Espacio |
Pausa de la animación |
Esc |
Salir |
El HUD esquina sup-izq muestra FPS, rayos/frame, rebotes, posición de cámara.
Stack
- glam — matemática 3D (
Vec3,Mat4, quaternions).fast-mathactivado. - crossterm — control crudo del terminal (raw mode, alt screen, eventos).
- ratatui — orquesta el frame y compone el HUD encima del viewport 3D.
- rayon — traza scanlines en paralelo (sin él el framerate se hunde en terminales medianos).
Arquitectura
src/
├── main.rs entry point
├── engine.rs loop, input, lifecycle del terminal
├── hud.rs overlay ratatui (stats + ayuda)
├── math.rs Ray, Hit, helpers sobre glam
└── render/
├── mod.rs
├── framebuffer.rs buffer RGB + Widget half-blocks ▀
├── camera.rs pinhole (yaw/pitch/fov), generación de rayos
├── scene.rs Sphere, Plane, Material, Light, Scene::demo()
└── tracer.rs ray tracer paralelo + Blinn-Phong + sombras + 1 rebote
El viewport 3D es un Widget custom de ratatui. Esto permite que crossterm
gestione el render bruto y ratatui orqueste, sin pelearse por el control de
pantalla.
Demo
La escena por defecto monta:
- Plano suelo con material ajedrez procedural.
- 4 esferas (lambertian roja, espejo azul, mate amarilla, espejo casi puro).
- 2 luces puntuales (cálida + fría).
- Cielo gradiente vertical.
- 2 esferas orbitan automáticamente para que el movimiento sea visible sin tocar nada.
Roadmap corto
- SSAA con muestras Halton(2,3), 1–16 spp ajustable en runtime.
- BVH cuando metamos mallas (las primitivas analíticas no lo necesitan).
- Carga
.objy rasterización de triángulos. - Mouse-look real (crossterm
EnableMouseCapture). - Materiales PBR (Cook-Torrance) y rugosidad.
- Soft shadows (jitter del rayo de sombra).
Verificación de firmas
Los commits van firmados con:
Pasqual Peñalver (Cypherpunks write code) <public@paski.dev>
EB82 8779 8FCD 2A89 4BFF DE35 017B F383 AB6B B586
Importa la clave pública desde un keyserver:
gpg --keyserver hkps://keys.openpgp.org --recv-keys EB8287798FCD2A894BFFDE35017BF383AB6BB586
Y verifica con tu herramienta favorita.
Licencia
MIT.