9 sezioni tecniche sono chiuse qui sotto. Apri quelle che ti incuriosiscono, oppure tutte.

In breve

Ho insegnato agli assistenti di programmazione basati sull’IA a realizzare da soli brevi video animati: scegliere lo strumento giusto, pianificare le scene, guardare i propri fotogrammi, correggere ciò che non va e consegnare un video finito. Ho provato dieci strumenti di animazione e ne ho tenuti quattro.

Il risultato è un insieme di istruzioni riutilizzabile, e lo scontro di 20 secondi tra un guerriero e un drago qui sotto l’ha realizzato un assistente seguendole. Le sezioni tecniche sono chiuse: aprile per i dettagli.

Cosa volevo

Volevo una skill di base per i miei agenti di programmazione chiamata /animation. Usata da sola, doveva prendere una richiesta dettagliata e lasciare che l’agente decidesse il framework, il flusso di lavoro e le tecniche di animazione. Usata come base, altre skill più specifiche dovevano poter ereditare da essa fissando in anticipo alcune di queste scelte.

Prima di scriverne anche solo una riga dovevo decidere quali framework dovesse usare. Sono partito da una lista di dieci: Blender, Godot, Three.js, Babylon.js, Panda3D, Bevy, Motion Canvas, Glaxnimate, StykAnimate e Stykz. L’intero studio, con ogni progetto, render e decisione, è ora pubblico.

Guerriero contro Drago, l’ultimo studio: 20 secondi, Godot 2D, scritto, renderizzato e controllato da un agente di programmazione seguendo la skill.

Repository su GitHub ↗Forgejo (canonico) ↗Mirror su Codeberg ↗

Un agente lavora tramite testo e una shell, quindi le funzionalità e la qualità visiva vengono dopo. Un framework è utilizzabile solo se offre all’agente quattro cose: scene come testo semplice che possa scrivere e confrontare con diff, un render eseguibile da un solo comando senza aprire finestre, fotogrammi identici a ogni esecuzione e render di singoli fotogrammi che possa aprire e ispezionare.

Quattro framework hanno superato la prova: Blender per il video 3D dove conta la resa dell’immagine, Godot per l’azione e il feeling da videogioco, Three.js per il 3D sul web e Motion Canvas per il video 2D programmato. Gli altri sono stati esclusi per motivi concreti: Babylon.js si sovrappone a Three.js, che i modelli conoscono meglio; Panda3D è datato; Bevy cambia API a ogni versione e i tempi di compilazione di Rust rallentano il ciclo modifica-render-controllo; Glaxnimate è uno strumento vettoriale di nicchia; Stykz è un’interfaccia grafica non mantenuta risalente al 2011 circa.

Motion Canvas aveva però un ostacolo: la sua ultima release su npm è la 3.17.2 di dicembre 2024 e renderizza solo tramite il suo editor nel browser. Revideo è un fork MIT mantenuto con lo stesso modello di scene e una funzione headless renderVideo(), perciò il percorso mantiene Motion Canvas per scrivere le scene e le renderizza con Revideo.

L’analisi completa dei framework ↗Revideo ↗Motion Canvas ↗

All’inizio sembrava che StykAnimate non esistesse: le ricerche trovavano solo Stykz. Si è rivelato essere uno studio per stick-figure con licenza GPL-3.0 nato da sei settimane per Windows, Linux e browser, con pose in cinematica inversa (IK), timeline a livelli con easing, camera che segue l’azione, effetti particellari ed esportazione MP4. Per i combattimenti tra stickman era lo strumento dedicato più valido della lista.

Leggere il codice sorgente ha chiuso la questione. Non c’è riga di comando, non c’è API di scripting e non c’è esportazione headless: ogni esportazione passa per una finestra di dialogo. È documentato solo il contenitore del file, non il JSON al suo interno. Un agente avrebbe potuto generare un progetto da far finire a una persona, ma non consegnare un video da solo, quindi l’ho scartato. Vale la pena tornarci se mai aggiungerà un render headless.

Codice sorgente di StykAnimate ↗

La skill trasforma una richiesta in un brief e in una scaletta temporizzata dei momenti chiave (beat sheet), sceglie il percorso e i metodi, prepara un progetto con un comando di render per ciascun tipo di output, imposta tutti i momenti chiave, osserva, rifinisce e renderizza. Ogni passaggio termina con una condizione di completamento verificabile, così l’agente non può dichiarare finito un lavoro a metà.

Il passaggio che fa funzionare tutto è Look (osserva). Un agente non può guardare un video in riproduzione: vede solo i fotogrammi che renderizza e apre. Perciò renderizza un’immagine fissa per ogni momento chiave e affianca le azioni rapide in fogli di contatto con il numero del fotogramma impresso su ogni riquadro, poi controlla ogni immagine rispetto alla scaletta: l’azione è leggibile, c’è qualcosa di tagliato fuori, la spaziatura varia in modo fluido, l’inquadratura mostra davvero ciò che conta in quel momento.

Le skill derivate estendono quella di base tramite slot: percorso, valori predefiniti del brief, metodi, stile, asset, controlli, output finale e passaggi aggiuntivi. Una skill per combattimenti tra stickman, ad esempio, può fissare il motore e fornire uno scheletro di partenza riutilizzando l’intero ciclo di lavoro.

Un foglio di contatto di 30 fotogrammi numerati che mostra un quadrato giallo muoversi con easing da sinistra a destra su sfondo scuro.
Un foglio di contatto dallo smoke test di Godot. I numeri rendono ogni problema riconducibile a un fotogramma preciso; la spaziatura mostra l’ease-in-out.

La skill ↗Come è progettata ↗

Le prime guide per ciascun framework venivano dalla documentazione. Poi ho fatto installare all’agente Blender 5.2.2 e Godot 4.7.2 e gli ho fatto eseguire ogni guida esattamente come era scritta. Tutti i percorsi hanno prodotto il render e ognuno di essi ha corretto la propria guida.

  • Blender 5.x ha rimosso Action.fcurves; le curve dei keyframe ora vivono in un channelbag per ciascun action slot.
  • Il flag --headless di Godot usa un renderer fittizio, quindi Movie Maker non registra nulla: serve un display o Xvfb.
  • Chromium in modalità headless renderizza WebGL via software per impostazione predefinita; --use-angle=vulkan --enable-gpu sposta il lavoro sulla GPU restando headless.
  • Il generatore di progetti di Revideo è interattivo, npm 11 blocca gli script di installazione necessari e lo script di render deve evitare il top-level await.

Toolchain e smoke test ↗Godot Movie Maker ↗Modifiche API di Blender 5.0 ↗

Successivamente ho chiesto una scena breve per ciascun framework, pensata attorno a ciò che quel motore fa meglio anziché a un soggetto unico. Blender ha ricevuto una sfera cromata che abbatte una torre di blocchi di vetro e ceramica, renderizzata con path tracing e simulazione di corpi rigidi precalcolata. Godot ha avuto un eroe che scaraventa via 36 slime guidati dalla fisica, con hit-stop, camera shake e particelle. Three.js ha mosso 14.400 cubi istanziati che si sollevano a formare una parola. Motion Canvas ha disegnato da sé il diagramma del ciclo della skill e un grafico dei tempi di render di ciascuna scena.

Il divario nei costi di calcolo è il dato più utile. Sulla mia GTX 745, Cycles ha richiesto circa 40 secondi per fotogramma a 1080p, Godot circa 0,33, la cattura di Three.js 0,08 e Revideo 0,024. I lunghi render di Cycles vanno lanciati in background mentre l’agente lavora ad altro, ed è proprio così che è stata prodotta quella dimostrazione.

Quattro fotogrammi in griglia: una torre di blocchi lucidi che crolla, un eroe circondato da slime rossi, cubi che formano la parola three.js e un diagramma del ciclo plan, block, look, polish, render.
La dimostrazione dei quattro percorsi: Blender, Godot, Three.js e Motion Canvas.

Resoconto della dimostrazione ↗Tutti i video ↗

Poi ho chiesto quale framework usare per il 2D. La risposta è stata: nessuno di quelli nuovi. Motion Canvas copre già la grafica vettoriale pulita e Godot copre il feeling da gioco 2D; l’unica lacuna era il tratto disegnato a mano, e Grease Pencil di Blender lo copre senza installare altro. Synfig, Spine, Rive, Manim e Remotion si sovrappongono a quei percorsi oppure richiedono l’uso interattivo di un editor.

Per verificare la ripartizione, l’agente ha realizzato lo stesso combattimento tra stickman tre volte a partire da un unico file di coreografia: inchiostro su carta con linee vibranti in Grease Pencil, motion graphics vettoriale piatta in Motion Canvas e scena da picchiaduro con barre della vita e bagliori in Godot. L’API Python di Grease Pencil è stata riscritta in Blender 4.3 e un dettaglio ha richiesto diverse prove: in 5.x un tratto viene riempito quando il suo fill_id è diverso da zero, non solo perché lo dice il materiale.

Un solo combattimento, tre percorsi 2D: Grease Pencil, Motion Canvas e Godot 2D che eseguono la stessa coreografia.

Analisi dei percorsi 2D ↗Grease Pencil in Blender 5.0 ↗

L’ultima richiesta era un combattimento di 20 secondi: un guerriero stilizzato con elmo, mantello, spada e scudo contro un drago, una volta in Godot 2D e una volta in Motion Canvas. Il drago atterra, ruggisce e sputa fuoco contro lo scudo; il guerriero gli colpisce il collo, fa una capriola all’indietro sopra un artiglio, viene scaraventato in una capriola a terra, scivola sulle ginocchia sotto una fiammata e lo finisce con un affondo dall’alto.

Nello studio 2D precedente la matematica delle pose era stata riscritta per ciascun motore. Questa volta un unico file Python calcola tutto una volta sola: tracce di keyframe, cinematica inversa a due ossa, un drago procedurale le cui ali dipendono solo da un valore di apertura e uno di battito, catene di Verlet per mantello e pennacchio, hit-stop come tempo d’azione congelato e movimenti di camera. Scrive le forme di ogni fotogramma in un file JSON. Godot e Motion Canvas non contengono alcuna logica di animazione: disegnano soltanto quelle forme ciascuno nel proprio stile, così i due video coincidono posa per posa.

Gli stessi dati alimentano un’anteprima rapida con Pillow che renderizza qualsiasi istante in circa un secondo. La coreografia è stata impostata e corretta lì prima ancora di toccare i due motori.

La versione Motion Canvas: gli stessi fotogrammi precalcolati disegnati come illustrazione vettoriale con cartelli dei titoli.
Quattro fotogrammi di anteprima rapida del guerriero e del drago disegnati con forme semplici su sfondo beige.
L’anteprima Pillow generata dai dati precalcolati, usata per impostare la coreografia prima di avviare qualsiasi motore.

Resoconto di Guerriero contro Drago ↗choreo.py ↗

Ogni scena dello studio è stata corretta attraverso il passaggio Look, e le correzioni sono state trovate misurando anziché tirando a indovinare. Quando il soffio di fuoco sembrava sbagliato, l’agente ha calcolato l’angolo del getto rispetto allo scudo dai dati salvati: 25 gradi verso il basso quando ne servivano 14. Quando in Godot è comparsa una foschia grigia, ha misurato la luminosità di un angolo fotogramma per fotogramma risalendo al blending in luce lineare sotto HDR.

  • Una sfera scritta per una tela larga 1920 pixel finiva fuori schermo su una larga 640.
  • Un salto attraversava dritto la testa del drago; ora il drago si impenna per colpire, esponendo il collo.
  • Le ali restavano alzate come vele quando il drago veniva ferito; ora si afflosciano e cadono a terra.
  • Godot registrava 2.592 triangolazioni di poligoni fallite finché ogni forma non è stata convertita in triangoli con area verificata.
  • Quattro hit-stop avevano spinto la posa di vittoria negli ultimi fotogrammi, quindi il finale è stato ritemporizzato.

Tutti gli intoppi e le relative correzioni ↗

I tempi di calcolo provengono da una sola macchina, una GTX 745 con un i7-4790S, spesso con più render in esecuzione contemporaneamente, quindi vanno letti in senso relativo. Tutte le clip sono mute. L’agente ha costruito e renderizzato; la mia parte è stata la regia e le decisioni, e la skill trasforma la verifica visiva del risultato in un passaggio che l’agente non può saltare.

La roadmap del repository elenca le direzioni aperte: skill derivate che estendono /animation attraverso i suoi slot, audio sincronizzato con la scaletta dei tempi e la trasformazione dell’approccio di precalcolo in una piccola libreria riutilizzabile. Tutto il necessario per rigenerare lo studio si trova nel repository.

Riprodurre lo studio ↗Roadmap ↗