Google+
3DVF Network :
ico_magazine
Magazine
ico_boutique
Boutique
ico_cgjobs
Portail Emploi
ico_upload
Hébergement d'image
ico_progiss
Progiss
Login
space
space

Accueil / Magazine / Didacticiels / L’animation temps réel dans les jeux vidéo, par David Lanier

space

L’animation temps réel dans les jeux vidéo, par David Lanier

Publié le 13 février 2009 par lieo
space

2.4. Notion de Motion capture pour les jeux vidéo


Dans la motion capture, on utilise un acteur pour récupérer ses mouvements. Pour ceci, on va disposer sur lui des capteurs. Puis on va utiliser une méthode pour récupérer les mouvements de ces capteurs et les transcrire dans notre format d’animation les keyframes.

Remarque : Les capteurs ne sont pas forcément disposés sur des articulations.

Il nous faut pour cela disposer d’un modèle 3D réalisé sous un package 3D avec un mesh et un squelette. C’est sur le squelette que nous allons localiser les points auxquels correspondent les capteurs de l’acteur de manière à répercuter les mouvements de celui-ci sur le squelette du modèle 3D. Dans le cas du jeu vidéo, les mouvements des capteurs sont retranscrits sous forme de keyframes. On utilise aussi un logiciel qui « nettoie » l’animation en enlevant ce qui est superflu.

Voyons précisément comment l’animation par squelette fonctionne.

3. L’animation par squelette

Nous allons ici étudier les différentes techniques utilisées dans les moteurs de jeux pour animer des personnages, monstres etc.





3.1. Squelette


On parle d’animation par squelette lorsque l’on a un mesh qui est déformé par un squelette. On peut voir ce squelette comme un squelette humain. on va y retrouver des bones tels que : le torse, les bras, avant bras, les cuisses (fémur), les tibias etc.

Dans le corps humain, ce sont les muscles qui donnent le mouvement, dans l’animation par squelette, ce sont les bones qui inculquent le mouvement au mesh.

Bien sûr on ne créé un bone que pour les parties que l’on désire animer, c’est-à-dire où l’on veut placer une articulation. Si les doigts d’un mesh n’ont pas besoin d’être animés, on ne placera pas de bones les représentants.

Remarque : Il faut savoir que plus le nombre de bones est grand dans un squelette plus le personnage sera lent à animer. Idem avec le nombre de vertices du mesh, plus il y en aura plus l’animation par squelette sera lente. Nous allons voir pourquoi.

Ce squelette est une représentation hiérarchique de bones. Il y a un parent à toute cette hiérarchie, que nous appellerons le bone root. Quand un bone est attaché à un autre, on parle de parent pour désigner le bone au dessus de lui dans la hiérarchie, de fils pour désigner le ou les bones en dessous de lui dans la hiérarchie et de frère pour désigner tous les bones qui ont le même parent.

Voyons ceci sur exemple de hiérarchie de bones :





 

Figure 5 : hiérarchie de bones

Chaque nom commençant par « Bip »est un nom de bone dans la hiérarchie. Le bone root est ici Bip01.

Chaque décalage indique un nouveau niveau de hiérarchie, les noms au même niveau comme « Bip01 Spine1 » et « Bip01 L Thigh » sont fils du même bone nommé “Bip01 Spine”.

Le bone “Bip01 Head” a comme parent “Bip01 Neck” et comme fils « Dummy21 ».

 

Notion de pose : Une pose c’est l’ensemble des matrices de transformation des bones à un instant donné. Elles permettent de définir l’état du squelette de manière unique.

On parle souvent de pose initiale, c’est celle dont on s’est servi pour associer le mesh au squelette. Dans cette pose spéciale, le mesh n’est pas déformé par le squelette.

 

La cinématique directe et inverse : on parle de cinématique directe lorsque l’on répercute le mouvement d’un bone sur tous ses fils. Dans le cas ou l’on bouge un bone et que l’on répercute le mouvement sur tous ses parents, on parle de cinématique inverse. On l’utilise par exemple lorsque une main se trouve sur un tiroir, au lieu de faire en sorte que la main tire le tiroir, c’est le tiroir qui pousse la main et on utilise de la cinématique inverse…

La répercussion des mouvements du squelette sur les vertices du mesh est appelé skinning.

 

Remarque : On ne récupère que les clés de rotations sur les bones car entre 2 bones, seul une rotation peut intervenir.


 

 

 

3.2.  Skinning


On appelle ce processus skinning car il est utilisé pour déformer un mesh représentant la peau du personnage par l’animation d’un squelette.

Comment fait-on le lien entre le squelette et le mesh ? Il faut que si le bone représentant un bras bouge, les vertices du mesh « proches » du bras bougent en même temps pour représenter sur le mesh la déformation.

Pour cela, on différencie 2 types de skinning le rigid et le smooth (appelé aussi blended). Voyons d’abord le cas le plus simple, le rigid skinning.



 

 



3.2.1. Rigid


On parle de rigid skinning lorsque chaque vertex du mesh n’est déformé (on dit aussi influencé) que par un et un seul bone à la fois.

Voyons un pseudo-algorithme (non optimisé)

 

 

 

Lorsque un bone est animé :

- on récupère le delta de rotation du bone.

- on transforme ce delta dans le repère du mesh.

- on récupère les vertices influencés par ce bone dans le mesh.

- on applique le delta sur chaque vertex et sur chaque normale au vertex.

 

Ceci nécessite d’avoir précalculé par quel bone est influencé chaque vertex du mesh. En général, cette opération est faite dans le package 3D, on récupère directement la correspondance vertex --> bone dans le moteur du jeu.

Le rigid skinning est peu coûteux mais il a un défaut visible sur les figures suivantes.

Voici un cylindre avec 2 bones à l’intérieur. Les 2 bones déforment le cylindre quand ils bougent.

Figure 6 : Cylindre avec 2 bones à l'intérieur - bones à l'état initial

 


 

Figure 7 : Cylindre avec 2 bones déformé par rigid skinning




Le rigid skinning ne produit pas des belles déformations aux jointures entre bones, c’est-à-dire aux articulations. On voit sur l’image les bones à l’intérieur du cylindre, le 2e bone a été plié de 90° et les vertices suivant la déformation produisent un effet d’étirement au dessus et un recouvrement en dessous de la pliure.

Pour remédier à cela, on introduit le smooth skinning. C’est le mode de skinning le plus couramment utilisé. Voyons d’abord le résultat que l’on obtient avec cette méthode sur le même cylindre :



 

Figure 8 : Cylindre avec 2 bones déformé par du smooth skinning


La différence est assez saisissante ! Voyons en quoi consiste le smooth skinning.




3.2.2. Smooth


On utilise non plus un seul bone pour influencer un vertex mais plusieurs. Chacun de ces bones a une influence appelée “un poids” sur un vertex. La somme des poids des bones déformant un vertex fait toujours 1. Si on veut qu’un vertex noté V soit influencé à 70% par un bone et à 30% par un autre, ces bones auront respectivement un poids de 0,7 et 0,3 par rapport à V.

 

Remarque : Un poids de 1 indiquerait que seul ce bone influencerait le vertex (rigid skinning). Un poids de 0 indique que le bone n’influencerait pas du tout le vertex.

Dans le rigid skinning, nous avions une correspondance 1 vertex --> 1 bone.

Dans le moothskinning, nous avons 1 vertex --> n bones avec n poids Wi tels que W0+ W1+… Wn = 1.

Le pseudo-algorithme pour le smooth skinning est le suivant :

-          on accède aux matrices des bones par un tableau contenant toutes les matrices. Si on a bien fait les choses, la matrice dans ce tableau est une matrice représentant le delta de rotation des bones exprimé dans le repère local du mesh, de manière à pouvoir l’appliquer directement sur les vertices.

-          Pour chaque vertex :

o        on récupère les matrices des n bones qui l’influencent ainsi que les poids correspondant à chaque matrice, les poids Wi sont normalisés (la somme vaut 1)

o        On modifie les vertices et les normales au vertex avec la formule suivante :

 


V = M0*V*W0 + M1*V*W1 + … + Mn*V*Wn

 

 


Dans cette formule, Mi est la matrice 4x4 du bone numéro i et Wi est un réel compris entre 0 et 1 représentant l’influence du bone sur le vertex. Et n est le nombre de bones influençant ce vertex.

En pratique : on limite le nombre de bones influençant un vertex à 4 de manière à ce que ce ne soit pas trop lent.

Dans l’animation de personnages, on se sert aussi d’une autre technique appelée « morphing ». voyons en quoi elle consiste.

 

 

 

4. Le morphing de meshes

 

Cette technique est assez connue du grand public. Elle consiste à transformer un mesh en un autre de manière progressive. Pour cela, on agit sur les vertices du premier mesh pour qu’ils atteignent les vertices de l’autre mesh progressivement.

Il faut avoir un mesh de référence et des meshes qui seront des cibles de morphing (morph targets). Ces derniers contiendront le même nombre de vertices que le mesh de référence mais avec des coordonnées de vertices différentes du mesh de référence. Il est possible de faire du morphing avec des cibles ne contenant pas le même nombre de vertices mais cela dépasse notre cadre.

 

Exemple : Voyons un mesh qui va être déformé et ses 2 cibles de morphing.




Nous voyons sur la figure précédente :

- le mesh de référence le plus à gauche, c’est un cube classique.

- Deux cibles de morphing : le cube du milieu, appelé ici cible 1 et celui de droite appelé ici cible 2 avec chacun un vertex déplacé par rapport au cube original de gauche. (Il serait possible de mettre plus de différences qu’un seul vertex)

- Sur cette figure, le mesh de référence n’est pas encore morphé, il est dans sa forme originale.

 

Le mesh final ( une fois le morphing effectué ) est une combinaison de ces meshes cibles. Pour spécifier comment on doit combiner les meshes cibles pour obtenir le mesh final, on donne un pourcentage à chaque cible.

 

Figure 9 : Morphing avec 2 cibles

Par exemple, si nous voulons que le mesh final contienne la forme de la cible 1, on va mettre le pourcentage de celle-ci à 100. Nous obtiendrons le résultat suivant :

 

On voit que notre mesh de référence à gauche s’est transformé en notre cible 1 ( le mesh du mileu)

 

Figure 10 : morphing avec cible 1 à 100%

Autre exemple :

 

On souhaite avoir la moitié de la déformation de la cible 1, pour ceci, on met son pourcentage à 50 et on obtient ceci :

 

Figure 11 : morphing avec cible 1 à 50%

Ou encore, avec 50% de la cible 1 et 50% de la cible 2, nous obtenons le mesh final suivant :

 

Figure 12 : morphing avec 50% de chaque cible

Ici le mesh référence, à gauche, est transformé à 50% par chaque cible.


Sur cette dernière figure, le mesh de référence se trouve le plus à droite.

Et au final pour le morphing, on spécifie le temps que doit durer le morphing pour que ce changement soit progressif.

 

Figure 13 : le même morphing que précédemment mais vu sous un autre angle

 

 

Voyons l’algorithme utilisé pour faire ce morphing. Pour cela, introduisons quelques structures :

 

 

struct VertDiff

{

Vec3f Diff ;

int VertIndex ;

} ;



Ceci va nous permettre de mémoriser les différences de vertices entre le mesh de référence et les cibles de morphing.

Nous avons un mesh de référence. Chaque cible doit avoir le même nombre de vertices que le mesh de référence.

 

 

- On commence par précalculer les différences entre les cibles et le mesh de référence. Pour cela :

 

o        On parcourt chaque mesh cible. On compare les coordonnées de chaque vertex avec celui possédant le même index dans le mesh de référence. S’il y a une différence, on mémorise l’index et la différence sous forme de vecteur 3D entre les 2 vertices dans une structure VertDiff décrite précédemment.

 

- Nous possédons maintenant pour chaque cible un ensemble de différences avec le mesh de référence entre vertices (VertDiff)

- Quand l’utilisateur spécifie un pourcentage pour une cible, par exemple il veut 50% de la cible i, on applique ce qui suit :

 

o        Pour chaque VertDiff noté vd de la cible i, on prend le vertex correspondant à l’index
vd->VertIndex dans le mesh de référence auquel on rajoute 50% de la différence mémorisée dans vd (vd->Diff).

Pour animer ceci au cours du temps, on fait une interpolation de type linéaire entre chaque différence de vertex de la même manière qu’au paragraphe sur les keyframes.

Pour faire le parallèle avec l’animation par keyframe, nous sommes dans un cas où nous pouvons considérer que nos clés d’animation sont : pour celle de départ, la position du vertex de référence et pour celle d’arrivée : la position du vertex de référence à laquelle on a ajouté la différence de vertex de ses cibles pondérées par le pourcentage rentré par l’utilisateur.

 

 

En pratique : On réalise par exemple l’animation faciale avec du morphing. C’est-à-dire que chaque phonème est représenté par une cible de morphing.



 

 

 

5. Glossaire


Ce glossaire comprend les divers termes que l’on retrouve dans ce document, il n’a pas pour prétention de détenir la définition mais juste de proposer une des définitions possibles.

La plupart de ces termes comprennent des mots en Anglais car le langage du jeu vidéo est basé sur des termes Anglais.

 

-          L’animation dans un jeu vidéo : L'animation sert à donner vie aux différents éléments du jeu (personnages, décors, etc.) pour servir son immersion et son esthétique.

-          Clés d’animation (Keyframes) : ce sont des informations retenues à un temps donné pour un objet, elles peuvent contenir par exemple une translation, une rotation ou un scale. On parle aussi du temps d’une clé qui est le temps auquel s’applique les informations retenues dans cette clé. En plus ce cela, on peut avoir des tangentes d’entrée et/ou de sortie d’une clé ou encore des paramètres pour reconstruire les tangentes.

-          Tangentes d’une clé d’animation, on différencie 2 tangentes pour une même clé, il y a la tangente in et out, In pour “arriver sur la clé” et out pour “quitter la clé”. Ces tangentes représentent un moyen de spécifier une vitesse et une direction pour arriver ou repartir d’une clé.

-          Interpolation : L’interpolation permet, à partir de 2 clés existantes, de calculer une valeur intermédiaire à un temps donné permettant de relier les 2 clés. On parle d’interpolation linéaire, de Bézier, d’Hermite, en TCB, en spline etc. Ces types d’interpolation permettent tous de passer d’une clé à une autre mais par des chemins différents.

-          Vertex : dans notre cas, c’est un point faisant partie d’une géométrie qui a une représentation 3D. Au pluriel, on parle de vertices.

-          Faces : les vertices d’un objet 3D sont regroupés en général par 3 pour former un triangle appelé face.

-          Mesh : c’est un objet géométrique 3D composé entre autres de vertices et de faces. On dit meshes au pluriel.

-          Bones(os) : c’est un des composants du squelette en animation de personnages de la même manière qu’un os est un composant du squelette humain. Il y a analogie entre les deux.

-          Squelette : ensemble des bones. Le squelette permet de déformer les meshes comme nous allons le voir dans l’animation des personnages. Entre 2 bones se trouve implicitement une articulation.

-          Boucle de jeu : C’est l’ensemble des fonctions du jeu qui sont appelées continuellement. On y retrouve l’affichage de la scène, la gestion du clavier ou de la manette, la gestion des sons etc. Il est cependant possible de n’appeler certains des composants de la boucle qu’une fois sur deux comme par exemple la gestion des entrées. Ceci afin de ne pas surcharger la boucle quand ce n’est pas nécessaire.

-          Frame : on dit par exemple qu’un jeu tourne à 60 FPS (frame per seconds), soit 60 images par secondes. On appelle ceci la vitesse d’affichage. Une frame correspond à un appel de la boucle du jeu.

-          Transformation : c’est ce qui contient la translation, la rotation et le scale d’un objet. On utilise souvent des matrices 4 x 4 comme dans Direct X. Cette transformation permet lorsque l’on a un vertex dans le repère du mesh de le passer dans le repère du monde en prémultipliant ce vertex par la transformation du mesh.

-          Courbe d’animation : lorsque l’on a une animation, par exemple sur une translation, il est possible de voir l’animation sur chaque composante x, y et z de cette translation. On obtient donc une courbe avec en abscisse le temps et en ordonnée la valeur de la composante à ce temps. C’est cette courbe qui est appelée la courbe d’animation.

-          Package 3D : on désigne sous ces termes un logiciel de 3D permettant la modélisation et l’animation d’objets 3D. On peut citer ici les logiciels les plus connus : 3D Studio MaxTM de Discreet, MayaTM d’Alias Wavefront ou encore XSITM/SoftimageTM d’Avid.

-          Moteur de jeu : programme exécutable regroupant les fonctionnalités basiques nécessaires à un jeu telles que l’affichage 3D, le son, la gestion des entrées (clavier, joystick), le gestionnaires de fichiers etc.

-          Phase d’export : pour récupérer les données graphiques provenant d’un package 3D, comme les meshes, textures, animations etc. On passe par une phase d’export. On exporte ces données du package 3D dans un format de fichier spécifique au moteur de jeu que nous développons.

-          Animation faciale : c’est une animation qui tend à faire correspondre ce que dit un personnage avec les mouvements de son visage et particulièrement sa bouche.

-          Phonème : c’est la plus petite unité du langage parlé. On lui associe une forme de bouche particulière qui correspond à cette sonorité. On l’utilise en animation faciale.


 

 

 

6. Références


Certains de ces liens peuvent ne plus exister au moment où vous lisez ceci.

 

Programmation des jeux vidéo


[ 1 ] http://www.gamasutra.com : site web référence en matière de développement de jeux vidéo.

[ 2 ] http://www.darwin3d.com : site avec du code source récupérable.
[ 3 ] http://www.gamedev.net articles.
[ 4 ] http://www.flipcode.com : articles avec code source.
[ 5 ] http://www.magic-software.com : théorie et code source récupérable, programmation graphique.

 

 

L’animation par ordinateur
[ 6 ] http://www.cs.virginia.edu/~dbrogan/CS551.851.animation.sp.2000/ : site contenant des références telles qu’articles, autres sites webs et livres.
[ 7 ] http://www.theory.org/software/qfa/writeup/writeup.html : algos de caméras, keyframes, slerp, squad quaternions.

 


 

 

7. Remerciements


Merci à tous ceux qui m’ont aidé à rédiger ce cours. Particulièrement Jean-Paul Digeon, Bruno Plantier, Fabrice Carré, Thierry Puginier, Gabriel Grasso, Stéphane Bura, Patrick Chen de Kalisto Entertainment et Michel Roger.

space
space

Les derniers commentaires (0)

Soyez le premier à déposer un commentaire.
space
space
space
space
space
A Propos | Contact | Publicité
Copyright © 2000-2018 3DVF. Tous droits réservés. | Infogérance serveur | tracker
space