Video 3D por código · sin IA de video

Crea video animado con código

Un cuarto y una casa armados pieza por pieza, con luz de verdad calculada en la tarjeta de video y narración con voz local.

Banner: reel 3D por código, cuarto armado pieza por pieza
En resumen

reel3d es un proyecto que hace videos cortos en 3D (formato 9:16, de celular) escribiendo la escena en código, sin usar un generador de video por inteligencia artificial. Cada mueble es una pieza con medida real, que entra animada a su lugar; la luz se calcula por path tracing (simulación de cómo la luz golpea y rebota en las superficies) en la tarjeta de video. Sirve para quien quiere mostrar ambientes, productos o ideas con control total de la cámara y del tiempo. Para ejecutarlo, necesitas Node.js, una tarjeta de video y paciencia: cada cuadro tarda algunos segundos.

Qué es

Una escena que tú escribes, no que tú sorteas

En vez de pedirle un video a una IA y cruzar los dedos, describes el ambiente en TypeScript. Todo es repetible: mismo código, mismo video.

Banner con las partes del proyecto: escena en código, path tracing, muebles CC0, narración local

🧱 Escena a escala real

Paredes, cama, armarios y mesadas son cajas con medidas en metros; los modelos listos (sofá, plantas, lámpara) vienen de Poly Haven, de uso libre (CC0).

💡 Luz fotorrealista

three-gpu-pathtracer acumula 64 muestras por cuadro con 4 rebotes de luz, y un filtro de ruido limpia el grano al final.

🎙️ Narración sincronizada

La voz se genera localmente (chatterbox, mediante inemavox); los tiempos de cada frase guían los planos de cámara y el subtítulo.

Cómo funciona

Del guion al MP4

Remotion abre la escena en un navegador sin pantalla, three.js arma el 3D y el path tracer calcula la luz cuadro a cuadro.

Guion (.txt)→ Narración por frase→ tempos.json→ Escena + cámara (src/)→ Path tracing en la GPU→ Filtro de ruido→ MP4 con voz

src/engine.tsx

El motor común: materiales PBR, cajas, carga de los modelos, planos de cámara, path tracing por cuadro y subtítulo palabra por palabra.

src/Quarto60.tsx · src/Casa90.tsx

Cada video es una composición: arma la escena e indica cuándo entra cada pieza y hacia dónde va la cámara.

produz.sh

Render completo, filtro de ruido, unión de la narración y una copia liviana (hasta 44 MB) para enviar por Telegram.

Requisitos previos

Qué necesitas tener

Probado en una NVIDIA GB10 (DGX Spark) con Linux ARM64. Cualquier GPU con Vulkan debería servir; solo cambia el tiempo.

Node.js 20+

Para Remotion y three.js.

node -v

GPU con Vulkan

El render usa --gl=angle (GPU de verdad). --gl=swangle cae a la CPU y queda muy lento.

vulkaninfo --summary

ffmpeg

Filtro de ruido, unión de la voz y compresión final.

ffmpeg -version
Guía de uso · paso a paso

Renderiza el cuarto y la casa

Los comandos de abajo son los mismos que se usaron para generar los dos videos de esta página.

1

Descarga el proyecto y las dependencias

Las texturas y modelos (217 MB, CC0) no van en el repositorio: el script descarga todo del CDN de Poly Haven a public/ph.

git clone https://github.com/inematds/reel3d-teste
cd reel3d-teste && npm install
node baixa-assets.mjs public/ph   # 132 archivos
2

Revisa un cuadro antes del video

Un cuadro suelto con pocas muestras muestra si la escena, la luz y la cámara están bien. Con debug, el tiempo de cada etapa aparece escrito en la imagen.

npx remotion still src/index.ts Quarto60 out/teste.jpg --frame=300 --gl=angle --props='{"spp":16,"debug":true}'
bash stills.sh Quarto60 16   # un cuadro por plano + hoja de contacto
3

Graba la narración (opcional)

Una línea de narr/quarto.txt por frase. gera.sh usa el TTS local de inemavox; cámbialo por tu voz de referencia. monta_audio.py une las frases y guarda los tiempos en narr/tempos.json; después de transcribir cada WAV con Whisper (palabra por palabra), la segunda etapa guarda las palabras del subtítulo.

bash narr/gera.sh
python3 narr/monta_audio.py             # frases → quarto.wav, casa.wav
python3 narr/monta_audio.py --palavras  # palabras del subtítulo
4

Renderiza el video completo

Una sola pestaña (una GPU), tope de memoria de 24 GB y límite de 6 h. Termina con el filtro de ruido y la narración en el MP4.

bash produz.sh Quarto60 "quarto 60 s"
bash produz.sh Casa90 "casa 90 s"
grep -a "Rendered" out/render.log | tail -1   # progreso

El último paso de produz.sh envía el video a un bot de Telegram local; sin él, el MP4 final queda en out/<nombre>-v1-final.mp4.

5

Ajusta la calidad

Más muestras = menos grano y más tiempo. Medido en la GB10 a 1080×1920:

ConfiguraciónTiempo por cuadroUso
spp 64 · bounces 4~5 svideo final (con filtro de ruido)
spp 256 · bounces 6~27 scuadro de portada, sin grano
Videos

Lo que ya salió de aquí

Los dos videos se renderizaron completos en esta máquina, sin ningún cuadro generado por IA.

Cuarto de 8 m² · 64 s. Armario hasta el techo, escritorio corrido en la ventana, cama elevada con cajones que se vuelven escalones. Render: 3 h 44.
Casa de una planta · 87 s. De la fachada hacia adentro: sala integrada, cocina en línea y, al final, el mismo cuarto. Render: 5 h 26.
Próximos

Hacia dónde va

Lo que ya se hizo y lo que viene a continuación.

Hecho
Cuarto 10 s, Cuarto 60 s y Casa 90 sMotor común, subtítulo palabra por palabra, narración con voz local y render completo en la GPU.
Próximo
La misma escena en BlenderRehacer el cuarto y la casa con Blender sin pantalla (Cycles), para comparar calidad, tiempo de render y costo de armado.