Cómo construimos a Maia (2/3): Soul, clips y loops
Tenía 20 composiciones y un personaje que se deformaba al moverse. Parte 2: por qué los modelos de video deforman, la regla de 'una cosa se mueve a la vez', el Soul que por fin ancló la identidad de Maia, y cómo se hacen loops de reposo que no saltan.
Cómo construimos a Maia (2/3): Soul, clips y loops
En la parte 1 quedé con un personaje que me encantaba y veinte composiciones aprobadas. Faltaba lo difícil: hacerla moverse. Y ahí Midjourney me pegó en la cara — entre un keyframe y el siguiente, Maia se deformaba. Esta es la parte donde el proyecto casi se cae, y cómo se levantó.
Primero: entender por qué se deforma
Mi error inicial fue tratarlo como un problema de calidad. No lo es, es de arquitectura: el modelo no anima el clip cuadro por cuadro, lo procesa entero de un jalón. No "camina" del keyframe A al B — interpola todo el clip de una vez.
Eso lo cambia todo. Si la pose o la posición en cuadro difieren mucho entre A y B, el modelo tiene que inventar el intermedio. Y ahí es donde gira sobre sí misma, cambia de casco o muda de traje. No está fallando: está rellenando un hueco que yo le dejé.
Regla de anclaje. Entre dos keyframes consecutivos se mantienen fijos: la pose (de pie / caminando / de espaldas), la posición en cuadro (si estaba en el tercio derecho, sigue ahí), la escala (nada de plano entero a figura diminuta) y el vestuario, descrito con las mismas palabras exactas. Lo que cambia es el entorno — luz, niebla, maquinaria—, no ella.
Corolario incómodo: los saltos de escala grandes no se resuelven en un clip. Se resuelven con corte escondido. Lo cual me llevó a la regla que ordenó toda la producción.
Una cosa se mueve a la vez
Midjourney hace un trabajo pésimo cuando combina movimiento de cámara + personaje caminando. No sostiene paralaje coherente y locomoción articulada al mismo tiempo: deforma la figura, patina el piso o rompe la perspectiva. Lo confirmé intentando un retroceso con grúa mientras ella se alejaba. Imposible.
- Cámara se mueve → personaje quieta.
- Personaje camina → cámara clavada.
- Nunca las dos con intención al mismo tiempo.
Suena a limitación. Terminó siendo la mejor decisión de dirección del corto, porque me obligó a resolver los cambios de encuadre con lenguaje de cine en vez de con movimiento gratis.
Las cuatro estrategias
1. Cambio por luz, cámara fija. El espacio se revela porque se enciende, no porque la cámara se mueva. Luces que prenden en secuencia, niebla que se disipa, un panel que despierta. El modelo lo hace bien porque solo anima intensidad. Es la estrategia dominante del corto: en el subsuelo son cinco slides seguidos con cero cortes, una sola posición de cámara y cinco estados de luz.
2. Barrido por oclusión. Algo pasa cerca de cámara (una columna, su cuerpo, un muro) y tapa el cuadro por completo. El corte se esconde ahí. Es el corte invisible de 1917. Requisito: el objeto que ocluye ya tiene que estar en la geometría de la escena.
3. Destello. Atravesar una fuente de luz satura el cuadro y el corte queda escondido en el flash. Es como se pasa del pasillo a la nave.
4. Movimiento de cámara por código. Para un push-in, un paneo o un tilt puros sobre un plato estático: se hace con transform de CSS o canvas sobre el still en alta resolución. Queda perfectamente limpio, sin artefactos, y cuesta cero generaciones.
El modelo debería hacer solo lo que solo él puede hacer: personaje y cambio ambiental. Los movimientos de cámara puros los hace mejor —y gratis— el código.
| Necesidad | Quién lo hace |
|---|---|
| Push-in / pull-back / paneo sobre plato fijo | Código (transform) |
| Personaje camina, cámara quieta | Modelo |
| El espacio se enciende o cambia | Modelo |
| Cambio de escenario | Destello u oclusión |
| Cámara compleja + personaje activo | Nadie — replantear la transición |
Y un error que sí me costó calidad
Midjourney permite 4 extensiones por cadena, así que usé 4. Mala idea: la calidad se degrada a partir de la tercera. Lo correcto son cadenas de 2 (tres frames por cadena) y generar imagen nueva por escena en vez de estirar. Más generaciones, pero sin degradación.
Bonus del mismo tipo: animar en baja y hacer el upscale al final, sobre el video terminado. Hacer upscale antes de animar mete artefactos que el modelo después amplifica.
Y aun así no alcanzó: el Soul
Con todas esas reglas los clips salían decentes. Pero la identidad seguía derivando: el casco cambiaba de forma, el abrigo mudaba entre frames. La consistencia por texto tiene techo, y yo ya lo había tocado.
La solución fue cambiar de herramienta para generar los frames. En Higgsfield el flujo se parte en tres piezas que se anclan por separado:
- El Soul de Maia ancla la cara. Es un modelo de identidad, no una descripción.
- Un estilo ("Silent Echo in Neon", a fuerza 0.8) ancla el mundo.
- Seedance hace las transiciones recibiendo los dos frames —inicial y final— y rellenando el movimiento entre ellos.
Esa última es la diferencia clave. Cuando el destino está fijado, el modelo no puede reinventar al personaje a medio camino: tiene que llegar exactamente al frame que le di.
Siete cosas que aprendí con el Soul
- El Soul solo ancla la CARA. El vestuario y el peinado hay que pedirlos explícitos en cada prompt o derivan igual:
long charcoal coat, short dark bob cut, siempre. - Proporciones de frente. El registro anime la hace chibi/achaparrada al ponerla de frente en plano abierto. Va siempre
FULL BODY, tall slender elegant adult proportions, long legs, small headcon negativoschibi, dwarf, squat, oversized head. - Cara de frente: o close-up real, o figura lejana. El punto medio —cuerpo entero de frente a media distancia— deforma el rostro. Y hay que revisar caras al 100%: en miniatura todo pasa.
- Interiores vs. calle.
INTERIOR, indoors, no sky, no roaden mayúsculas mantiene la nave y el subsuelo sin que el estilo los vuelva calle. Y no bajar la fuerza del estilo de 0.8: a 0.6 se pierde la identidad del mundo. - El modelo rechaza el picado cenital. Un descenso se logra con vista lateral de corte más escalera vertical. Nunca top-down.
- Negativos que resolvieron frames concretos:
no warning lights, alarm lights(la avería que ocurre sin que nada avise — la ausencia de alarma es el argumento),no people, workers(el puesto de trabajo vacío),no bright vertical masses,no city lights, dense skyline. - Dos generaciones bastan. El Soul es consistente; no hace falta pedir cuatro. Ahorro directo de créditos.
upright, correct gravity, head up con negativos upside down, inverted, rotated. Si un frame va a servir de keyframe para video, su orientación tiene que ser inequívoca en el prompt.Los loops: el problema que nadie ve venir
El corto no corre de principio a fin: se detiene en cada keyframe para que se lea el texto del slide. Y ahí aparece un problema que no había considerado — una foto congelada frente a 300 personas se siente muerta. El video corre, se para, y la sala nota el paro.
La solución fue un loop de reposo por frame: el ambiente se mueve, el personaje no. La receta es de una simpleza que da rabia no haber visto antes:
El frame inicial y el frame final del clip son el mismo keyframe. Así el clip regresa exacto al cuadro de partida y el loop cierra limpio, sin crossfade ni trucos de montaje.
Y el personaje se congela por prompt, con un bloque que se pega al final de cada loop:
Locked static shot, the camera does not move at all. The android woman stays
completely frozen like a statue in the exact same pose and position — no
character movement, no morphing, no walking, no turning, no head motion, no
limb motion. Only the environment animates, subtly and slowly.
Seamless ambient loop.
Cómo se verifica un loop sin usar el ojo
Revisar 20 loops a ojo es lento y traicionero. Los medí con PSNR, que compara dos imágenes y devuelve un número en decibeles: más alto = más parecidas.
# extraer primer, medio y ultimo cuadro
ffmpeg -i loop.mp4 -vf "select=eq(n\,0)" -frames:v 1 a.png
ffmpeg -i loop.mp4 -vf "select=eq(n\,60)" -frames:v 1 m.png
ffmpeg -sseof -0.1 -i loop.mp4 -frames:v 1 z.png
# empalme del loop: primer vs ultimo -> quiero > 36 dB
ffmpeg -i a.png -i z.png -lavfi psnr -f null -
# intensidad del movimiento: primer vs medio -> quiero > 30 dB
ffmpeg -i a.png -i m.png -lavfi psnr -f null -
- Empalme > 36 dB = el clip regresa a su propio cuadro, el loop no salta.
- Movimiento > 30 dB = el ambiente se mueve lo justo, sin llamar la atención.
Uno de los primeros loops dio 17.9 dB de movimiento. Se rechazó sin discutir y se regeneró más sutil. Ese número me ahorró proyectar un fondo que le hubiera robado la mirada al texto.
El artefacto que aparece siempre
Hay un patrón que el modelo de video repite: a media generación le mete al personaje un rim neón violeta —un contorno luminoso en la silueta, o líneas brillantes en la cara y el cuello— que no está en el frame de origen.
no glowing outline, no neon rim/edge light,
no glowing lines on face/skin/collar/clothing
Dos hallazgos de utilería
Boomerang para clips que casi loopean. Si un loop queda bueno pero no cierra del todo, se pega su propio reverso: sale y regresa al cuadro cero por construcción.
ffmpeg -i in.mp4 -filter_complex \
"[0:v]split[a][b];[b]reverse,trim=start_frame=1,setpts=PTS-STARTPTS[r];[a][r]concat" \
-c:v libopenh264 -b:v 6M -y out.mp4
(Uso libopenh264 porque en mi máquina ese ffmpeg no trae libx264 ni acceso a GPU. Detalle tonto que me costó media hora.)
Kling exige dos imágenes distintas. Probando otro modelo para los loops, todas las llamadas fallaban en silencio cuando le mandaba el mismo frame como inicio y fin. Necesita que técnicamente sean dos objetos distintos —el frame como generación y el mismo frame importado como archivo— aunque el contenido sea idéntico. Con eso encola y termina bien, y da loops muy sutiles con bloqueo férreo del personaje: ideal para las caras.
La decisión que salvó el calendario
Con 22 frames, animar todos habría sido una semana más. Así que no los animé todos: solo once llevan loop —los hero y los de ambiente rico—. Los otros ocho se quedaron como still.
Y no se nota. Porque entre slide y slide siempre hay una transición en movimiento, el ojo llega al frame estático con el movimiento reciente todavía en la memoria. El truco es dónde pones el movimiento, no cuánto pones.
Los prompts completos de esta parte —las cuatro estrategias, la receta del Soul, el bloque de bloqueo de los loops y las 21 transiciones— están en el repo público: github.com/andyeswong/maia-prompts, en prompts/04, 05, 06 y 07.
Dónde quedamos
Al final de esta etapa tenía los 22 frames, las 21 transiciones y los loops. Tenía un corto. Lo que no tenía era cómo presentarlo: un video corrido no sirve para dar una plática — necesitas parar donde tú quieras, avanzar cuando tú quieras, y que el texto de cada slide caiga encima en el momento exacto. Faltando días, no existía el reproductor.
Parte 3 — De la tarima a producción: la presentación y la web. El reproductor que me dejó controlar el corto desde el celular en el escenario, qué pasó realmente frente a las 300 personas, y por qué el mismo lenguaje visual terminó siendo el sitio de Purple AI. Próximo viernes.
artículos_relacionados
Cómo construimos a Maia (3/3): de la tarima a producción
Un video corrido no sirve para dar una plática. Parte 3: el reproductor con control remoto desde el teléfono que usé frente a 300 personas, y por qué ese mismo corto terminó convertido en el sitio de Purple AI.
Cómo construimos a Maia (1/3): del moodboard a Midjourney
Presenté FOROTEC 2026 con un corto en vez de diapositivas, protagonizado por un personaje: Maia. Parte 1 de cómo la construimos: la decisión del casco sin rostro, los moodboards de Midjourney y por qué el estilo saltó de fotorrealista a anime.
IA en Producción: Lo que Presenté en FOROTEC Tijuana 2026 (y Por Qué la Protagonista Fue Maia)
Resumen de mi ponencia en FOROTEC Tijuana 2026: tres casos reales de IA en producción (Esquer Luken, Assessment, Karen), el número que costó $11,500 pesos, los tres dolores reales de producir IA, y por qué esta vez conté todo con un corto cinematográfico protagonizado por Maia en vez de un deck de bullets.