Animación de color plano
Un dibujo se mantiene durante 3–4 fotogramas, y el rendimiento proviene de intercambiar dibujos y formas de boca. Para diseños simples de caricatura de TV, esta es la ruta donde los modelos de imagen se mantienen más consistentes. No necesita ni 3D ni un modelo de video.
Los scripts están en la carpeta scripts/ de esta skill, con rutas relativas a este SKILL.md. A continuación, $S significa esa carpeta. Excepto por new_project.py, ejecútalos desde la carpeta de la película. Para problemas de entorno, usa dula-start.
Habla con la persona en su propio idioma.
Flujo de trabajo
python $S/new_project.py mi_pelicula && cd mi_pelicula
1. Historia y tomas
Escribe story.md, luego config/film.json (consulta la referencia de film.json). Mantén la primera película en 20–30 segundos, y una línea hablada toma aproximadamente 2–3 segundos, por lo que 15 segundos contienen 3–5 líneas. Usa solo personajes originales.
Para cada línea, piensa quién la dice, a quién y a quién muestra la cámara. Los chistes no deben depender de palabras que el público no entienda. La causa y el efecto también necesitan dibujos (entra corriendo → agarra → el objeto sale volando). No lo saltes con un corte.
2. Diseños de personajes (el paso más importante)
Coloca cada personaje en config/anchors.tsv (nombre<TAB>apariencia), luego ejecuta:
python $S/paint.py anchors config/anchors.tsv
Abre y mira cada imagen tú mismo. Algunos visores muestran un área transparente como un brillo de color sobre negro, que parece un recorte fallido. Si tienes dudas, revisa build/check_alpha.png del paso 3. Luego muestra los diseños a la persona y obtén su aprobación antes de continuar. Cada dibujo posterior sigue estos, por lo que un error aquí es el más costoso de corregir. Arregla las proporciones en palabras, como "cabeza un tercio de la altura total, cara redonda, ojos pequeños de cuenta negra, overol rojo".
3. Fondos y dibujos
Completa config/plates.tsv (nombre<TAB>descripción) y config/cels.tsv (dibujo<TAB>personaje<TAB>pose). Comienza los nombres de los dibujos con el nombre del personaje, por ejemplo heroe_correr_a.
python $S/paint.py plates config/plates.tsv
python $S/paint.py cels config/cels.tsv
python $S/prep_cels.py --bases-only # Revisa los recortes en build/check_alpha.png antes de pintar bocas
Las imágenes tardan de 1 a 3 minutos cada una, y paint.py informa el progreso a medida que avanza. Si tu herramienta detiene comandos largos, ejecútala en segundo plano. Una re-ejecución omite las imágenes terminadas. Para rehacer una, usa --only <nombre> --force.
Para mantener la continuidad de dibujos y lugares, agrega una columna más que indique a qué seguir:
heroe_correr_a hereo Corriendo hacia la derecha, pie izquierdo adelante.
heroe_correr_b hereo Corriendo hacia la derecha, pie derecho adelante. hereo_correr_a
prado Un prado bajo nubes grises de lluvia.
prado_sol La lluvia ha parado y el sol se abre paso. prado
Reglas:
- Dibuja un personaje por imagen. El diseño del personaje es siempre la primera referencia. Nunca uses una imagen rechazada como referencia.
- Decide primero hacia dónde miran los personajes. Las imágenes generadas una a la vez eligen una dirección cada una, por lo que dos personas en una conversación pueden terminar fácilmente de espaldas. Especifícalo de antemano y usa
flippara corregir errores. - Cada dibujo en un ciclo de acción sigue al anterior (la columna adicional anterior), por lo que la dirección, la escala y la forma se mantienen estables. Sin esto, un ciclo parpadea.
- Para un cambio en la hora del día, vuelve a pintar el fondo, siguiendo la placa original. Multiplicar un color no puede ocultar un cielo azul.
- Revisa las proporciones de un personaje en cada toma. Una descripción de pose como "cuello estirado hacia arriba" puede convertir a un cuerpo diferente.
4. Bocas y parpadeos
Cada dibujo que habla recibe ediciones locales de la misma imagen. En config/variants.tsv:
heroe_parado_m1 hereo_parado Cambia solo la boca a medio abierta, óvalo pequeño.
heroe_parado_m2 hereo_parado Cambia solo la boca a completamente abierta.
heroe_parado_parpadeo hereo_parado Cierra ambos ojos como líneas curvas simples. No cambies nada más.
Nombres: <base>_m1 es medio abierta, y <base>_m2 es completamente abierta. Con solo _m1, la boca tiene dos estados, abierta y cerrada, y eso también funciona. El dibujo base debe tener la boca cerrada. Si está dibujado con la boca abierta, haz una variante cerrada y establece los tres estados con talk en film.json.
Cada dibujo de un personaje que habla necesita sus propias bocas, incluido cada dibujo en un ciclo de caminata.
python $S/paint.py variants config/variants.tsv
python $S/prep_cels.py
prep_cels.py convierte los dibujos en color plano verdadero y bloquea cada variante a su base. Luego abre build/check_alpha.png y revisa los recortes sobre magenta. Vuelve a dibujar cualquier imagen con fondo sobrante, piezas faltantes u ojos borrados. Si advierte sobre un área grande cambiada, el modelo editó el cuerpo. Agrega una ventana x,y,w,h como columna 4 de variants.tsv.
¿Los colores se desvían? Puedes agregar config/palette.json ({"piel": [250, 220, 190]}), usando colores muestreados del diseño del personaje. Solo los colores cercanos se ajustan a él, y prep_cels.py lo aplica nuevamente después de que lo cambies.
5. Sonido
Elige una opción:
- Genera voces con
dula-voice, usando la propia clave de la persona. - Usa audio existente: colócalo en
audio/voice/<id de línea>.wav, o establecefileen la línea. mp3 y wav funcionan ambos. - Haz un borrador sin sonido: dale a la línea un valor
seconds.
Las bocas se calculan a partir de este audio, así que define las voces antes de hacer la prueba.
Opcional: ambience, bgm, sfx y songs. Usa solo material sobre el que la persona tenga derechos. Este proyecto no genera música. Sin música con licencia, omite la banda sonora y deja que la ambientación y los efectos de sonido lleven la película.
6. Prueba
python $S/build_film.py
python $S/render.py --stills 1,3,5,8,12
python $S/render.py --range 0,20 -o output/piloto.mp4
build_film.py se detiene con un error cuando un personaje visible habla pero su boca no puede moverse, el error más fácil de pasar por alto. Mira cada fotograma fijo antes de mostrar la prueba. No esperes a que toda la película esté terminada para mostrarla a alguien.
Para colocar un personaje en el suelo: adivina ground, renderiza un fotograma fijo y ajusta. Es más rápido que calcularlo.
No dejes que las tomas permanezcan estáticas. A menos que un tiempo esté destinado a estar quieto, dale a cada toma una cosa que se mueva: un paneo en la placa, un bob o shake, un cambio de dibujo, o una superposición como lluvia. Termina la película con fade_out en la última toma.
7. Película completa y revisión final
python $S/render.py
python $S/check_mouths.py
Confirma cada uno de estos puntos antes de entregar, y di claramente si no pudiste:
- Miraste un fotograma real de cada toma
-
check_mouths.pyno informa bocas congeladas - Cada personaje sigue viéndose como la misma persona a través de las tomas (la cara y las proporciones importan más que el color)
- Las personas en una conversación se miran entre sí
- Un solo dibujo moviéndose por la pantalla tiene un
bobo más dibujos, o se lee como deslizamiento - Escuchaste el audio. Si no puedes escuchar, di que el audio no ha sido revisado de oído
Un ejemplo completo
examples/rainy-slide en este repositorio tiene los prompts y la lista de tomas de una película terminada de 15 segundos, y docs/tutorial.md lo explica. Encuéntralos en ../../examples/rainy-slide y ../../docs/tutorial.md desde este archivo. Úsalos como modelo cuando alguien pida uno.
Ritmo
Reglas generales: las tomas duran en promedio 3–5 segundos, los personajes mantienen cada dibujo durante 3–4 fotogramas (aproximadamente 7 dibujos por segundo), con primeros planos frecuentes y expresiones exageradas. hold es el número de fotogramas por dibujo.
Problemas comunes
| Síntoma | Causa y solución |
|---|---|
| Los colores del cuerpo parpadean al cambiar las bocas | La variante no pasó por prep_cels.py |
| Una caminata o carrera late alto y bajo | No dimensiones los dibujos por separado. Un actor comparte una escala automáticamente. Agrega también align_head |
| Un accesorio toma el color incorrecto | Una entrada de la paleta está demasiado cerca. Elimínala o baja SNAP |
| La boca permanece abierta durante el habla | Las bocas de dos estados usan un umbral de 0.5. Verifica si el audio está apagado |
| Las palabras suaves permanecen cerradas | Una palabra fuerte establece la escala para su línea. Agrega un _m2, o baja mouth_open_at en la línea |
| La lluvia o el viento no se oyen | La ambientación es baja por defecto. Dale un level_db, como -35 |
| Silbido constante | El clip de ambientación es solo ruido. Reemplázalo. La ganancia está limitada, por lo que no se amplificará más |
| Codex dice que la imagen de referencia se perdió | La generación de imágenes debe ser su primera acción. paint.py maneja esto, así que ejecútalo de nuevo |
Limitaciones
Esta ruta no es adecuada para peleas complejas, acción continua larga o pintura realista.