Hein ? Quoi ? Comment ?!  Plus d'un mois sans article autour de Seasons after Fall ?

Mais que fait-on ? Que fait Buster ?

Nous avons été quelque peu occupés durant ce mois de novembre, vous découvrirez le pourquoi du comment dans de futurs posts.

Pour l'heure, laissez moi tenter de réparer ce manquement avec un article légèrement technique décrivant une fonctionnalité que nous avons fraichement ajouté à notre moteur maison : l'animation par spritesheet.

Avant de déployer mon plus beau Prout (le penchant maléfique et chiant de Proust), passons au crible quelques termes qui pourraient être utiles à la compréhension. Les gens bien au fait ou pressés peuvent directement passer la section suivante (sans passer par la case "roh mais l'autre il me prend pour qui") !

 

>> Vocabulaire

Vertex

Un vertex est un point dans l'espace tri-dimensionel. A ne pas confondre avec un Game Object (cf. le tutoriel Unity). Non, un vertex c'est l'élément de base qui sert à modéliser des objets (2D ou 3D).

Généralement, un vertex possède une position (x, y, z) ainsi qu'une couleur (rouge, vert, bleu, transparence) mais aussi des coordonnées de texture (u, v). Je passe sur les propriétés qui ne nous intéressent pas (comme la normale nx, ny, nz).

Autant d'information dans un si petit corps : le vertex !

 

Quadrilatère (Quad de son petit nom)

Un quad est un assemblage de deux triangles (je ne vous fais pas l'affront de décrire un triangle). Le tout constituant une forme parallélépipèdique. Vous l'aurez compris, un quad est composé de 4 vertices (pluriel de vertex), les 2 triangles le composant ayant un côté en commun. 

Deux triangles siamois forment un quad

 

Texture

Une texture est une image que l'on vient plaquer sur des triangles (ou des quads) pour leur donner un peu de gaieté et éviter qu'ils n'arborent une bien triste robe de couleur uniforme.

Revoici notre quad, cette fois-ci vêtu d'une texture de sous-marin (et oui, on est corporate ou on ne l'est pas !)

C'est pas la plus belle texture que vous ayez jamais vu ? Hein ? Hein ?

 

Coordonnées de texture (UV)

Les coordonnées de texture (souvent décrites comme "UV", rien à voir avec le soleil et le bronzage) sont une des propriétés des vertices. On trouve 2 coordonées : U et V (haha, je vous avais dis que ça avait rien à voir avec le bronzage).

Ces deux coordonnées indiquent un emplacement dans une texture (une sorte de coordonnée GPS dans une image), elles vont permettre à un vertex d'obtenir une couleur issue d'une texture.

La texture est alors appliquée à un triangle grâce à l'interpolation des coordonnées de textures des 3 vertices composant le triangle.

Revoici notre quad habillé pour l'hiver, mais cette fois-ci les coordonnées de textures sont différentes des précédentes et le quad arbore une sous-partie de la texture du sous-marin.

Les UV sont bien utiles pour habiller des quads comme vous le voulez

 

>> Construire une spritesheet

Préparation

Disons que nous voulons animer le personnage de Braid (Tim). Si vous voulez réaliser ça chez vous, vous trouverez les images de Tim sur le site du graphiste.

Pour obtenir un personnage animé, vous prenez un artiste 2D talentueux et vous le laissez dessiner une séquence d'images représentant le personnage en pleine action.

Voici quelques étapes issues de la course de Tim :

Uno, dos, très

Tel un animateur 2D ancestral, l'artiste dessine une étape donnée en la superposant avec une étape précédente, grâce à l'usage de calques. C'est une technique d'animation largement utilisée dans les dessins animés traditionnels impliquant une planche à dessin, un crayon, du papier calque, du scotch, une gomme et pas mal de patience :

La Chose est très à l'aise quand il s'agit d'animer

Cette technique devrait vous remémorer vos cours, pendant lesquels vous gribouilliez sur un coin de cahier de brouillon pendant de longues minutes avant de découvrir votre superbe animation 3 images par seconde à la sonnerie retentissante !

Imaginez le en mouvement, et ça éblouira votre esprit

 

Construction

Maintenant que nous avons les dessins des différentes étapes de notre animation, il est temps de construire cette fameuse "spritesheet".

Une spritesheet est simplement le rassemblement de toutes nos petites images dans une image plus grosse. Voici l'exemple de la course de Tim :

Une image pour les contenir toutes !

 

 

Vous remarquerez qu'il y a un gros espace vide en bas
de l'image. C'est pas moi qui ait forcé sur le retour chariot tel un forcené, c'est juste un espace laissé vaquant dans la spritesheet. On peut facilement imaginer y insérer des images de Tim en train de bondir ou de chuter.

Dans cette spritesheet, j'ai décidé de laisser un espace régulier entre les images. On se retrouve donc avec une grille régulière d'images. 

Une grille régulière, et un espace vide (et non pas une armée de retours chariot)

 

Vous n'êtes pas forcés d'utiliser une répartition régulière, mais c'est plus facile pour gérer automatiquement la construction d'une animation. La vraie texture du jeu Braid n'utilise pas de grille régulière pour répartir les éléments. Regardez par vous-même !

C'est un peu l'anarchie

 

>> Pourquoi utiliser une spritesheet ?

Vous vous demandez surement pourquoi on s'embête à vouloir absolument rassembler toutes les petites images dans une plus grande (la spritesheet), alors que les animations de nos enfances dans les cahiers de brouillon fonctionnaient très bien avec des images séparées !

Il y a beaucoup d'avantages :

* Eviter le changement de texture :

Comme on utilise une grosse texture en contenant plusieurs petites, on réduit la nécessité de changer de textures lors du dessins 3D (ou 2D). Changer de texture lors du rendu a un coût non négligeable en terme de temps perdu. Eviter de changer de texture évite donc de perdre du temps (pour le perdre ailleurs).

* Chargement plus rapide :

C'est plus rapide de charger une grosse texture que plein de petites. On passe moins de temps à lire plein de choses différentes en utilisant des spritesheets... et on réduit par la même les temps de chargement.

* Les sprites peuvent être dimensionnées comme bon nous semble :

S'il est une chose difficile pour un graphiste, c'est bien d'avoir à redimensionner ses textures de sorte qu'elles soient d'une hauteur/largeur en puissance de 2 (32/64/128/256, etc...). Ceci pour maximiser le stockage, l'accès et la compatibilité sur un maximum de carte graphique (et vous savez comme moi qu'il y en a un paquet de différentes).

En utilisant une spritesheet, seule cette dernière nécessite d'être taillée en dimensions puissances de 2. Dès lors les sprites qui y sont inclus peuvent avoir des dimensions complètement loufoques, et tant pis si on ne remplit pas toute la spritesheet.

 

>> Animation avec une spritesheet

Pour animer un quad texturé avec une spritesheet, on opère simplement des glissements d'UV (coordonnées de texture) au cours du temps :

Elles sont pas belles et claires mes flèches moches ?

Au lieu d'aller de texture en texture (comme on irait en coin de cahier de brouillon en coin de cahier de brouillon), on habille simplement le quad avec une sous-partie de la spritesheet et on déplace cette sous-partie.

 

>> Atlas de texture/Tilemap

Un atlas de texture ou une tilemap sont des termes qui vous sont peut être déjà familiers. Ce sont des sortes de spritesheets, à la différence que ces textures ne servent pas à animer des choses, mais plutôt à bénéficier de quelques avantages des spritesheets comme la réduction du nombre de changements de textures et la rapidité de chargement.

Exemple d'une tilemap qui peut suffire à texturer un niveau entier ! (dans Pyramide, on dirait "en un !')

 

>> Notre implémentation dans Blender

Comme à notre habitude, on use et abuse
des courbes Blender pour faire tout et n'importe quoi. L'animation par spritesheet ne déroge pas à la règle !

Voici Tim dans notre Blender custom :

Ah il sait plus où il est le Tim là !

 

Comme vous pouvez le constater, les courbes (une rouge, une verte) sur la partie droite de l'image sont très simples puisqu'elles prennent la forme d'un signal "carré". Elles indiquent simplement le nombre de décalages de cases que l'on doit opérer en U (rouge, horizontalement) et en V (vert, verticalement) dans la spritesheet.

Dans l'exemple, la posture prise par Tim est due au fait que la courbe rouge indique un offset de 4 et la courbe verte un offset de 1, ce qui nous renvoie à la sous-image entourée en blanc dans la mini spritesheet reportée à l'écran.

Bien entendu, on dispose d'un wizard pour construire les courbes rouge et verte automatiquement. Le wizard demande juste des informations comme le nombre d'images de l'animation, la vitesse de défilement des images ou encore le point de départ de l'animation.

 

>> Utilisation dans le jeu

Pour le moment, Seasons after Fall utilise grandement l'animation par morphing de polygones. Mais ceci peut être coûteux si trop d'éléments à l'écran sont animés de la sorte.

Si nous devons animer un champ de petits brins d'herbe, alors l'utilisation d'une spritesheet sera bien plus efficace en terme de performances que notre classique morphing de mesh.

On pense aussi à utiliser les spritesheet pour réaliser de petits tutoriels animés. Notre modèle absolu pour en la matière est l'excellentissime Machinarium. Le but étant de limiter, voire d'anéantir, toute trace de textes à l'écran et ainsi rendre le tout plus universel (non, pas Vivendi, l'autre).

 

>> Résultat in-game

Voici un petit aperçu de ce que donne notre cher Tim dans le moteur de Seasons.

J'ai rajouté dans cette scène un blob animé lui aussi grâce à une spritesheet trouvée dans un tutoriel du blog de Retro Affect (les gars derrière le très prometteur Snapshot). J'ai aussi ajouté ma touche personnelle de programmeur avec des choses de toute beauté qui vous rendront épileptique (ne me remerciez pas).

 

Comme vous pouvez le voir, ça fait un paquet de Tim en même temps. Pour éviter que ces Tim n'aient l'air de faire une marche synchronisée disgracieuse, on inculque des petits temps de décalages dans les timelines d'animation de chaque Tim.

Pour finir, on note que les éléments animés en spritesheet peuvent très bien subir des rotations et autres déplacements ou changement d'échelles (cf. les trucs qui rendent épileptique sur la droite de la scène).

Et si vous voulez voir d'autres utilisations de spritesheets, je ne saurai que trop vous conseiller d'aller faire un tour sur le très bon blog GB de krys64 (Unity inside) !

 

A la prochaine, pour de nouvelles aventures pixelisées !

Guillaume