Aide pour After Effect, techniques, expressions.

vendredi 19 février 2010

suivi d'objet

Animer un objet dans After Effect est une chose, animer une caméra en est une autre.
C'est parfois compliqué, fourbe, ingrat, ça fait pas ce qu'on veut, bref.




Nous allons en partie régler le problème pour un cas bien particulier, celui du suivi d'un objet dont le mouvement est important et plus ou moins chaotique, comme une mouche par exemple.

Nous allons essayer d'imiter le comportement d'un vrai caméraman.
Que fait le caméraman ? Il essaye tant bien que mal de suivre la trajectoire de l'objet pour le garder dans son cadre, en étant parfois en retard sur l'objet en question ou parfois un peu en avance s'il a anticipé.

Dans l'exemple, il s'agit d'un gros wiggle 3d bien large (le cercle fait 100 de large, le wiggle se déplace en tout sur 2000). Les particules sont là pour avoir un élément fixe pour que vous puissiez différencier le mouvement de la caméra et celui de l'objet.

Nous allons donc créer une expression sur le point ciblé de la caméra. La caméra en elle-même restera fixe.
Pour créer le caméraman parfait, il suffit logiquement de coller la position de l'objet au point ciblé par la caméra, et l'objet restera donc toujours au centre de l'image. Mais ça n'est pas ce que nous voulons faire.

Créez votre petite scène, et rajoutez un Null objet que nous appellerons "target cam". C'est à lui que nous allons appliquer l'expression et non à la caméra. Vous verrez un peu plus tard pourquoi.

Ajoutez 3 paramètres glissière à ce Null, et nommez les "amplitude", "tendance" et decalage".

amplitude définira le nombre d'images maximum de décalage dans le temps. (mettez 20 par exemple)
tendance nous permettra de définir si la camera sera plus souvent en retard ou en avance. (mettez -1 pour le moment)
decalage contiendra la valeur de décalage temporel à chaque image.

Écrivons l'expression dans "decalage" :

amp=effect("amplitude")("Curseur");
tendance=effect("tendance")("Curseur");

Expliquons un peut le processus avant de se lancer dans l'écriture de l'expression.
"decalage" va contenir un wiggle qui va faire varier le décalage temporel, selon l'amplitude.
Pour le moment, si on écrit juste "wiggle(0.2,amp), on va avoir une valeur qui va varier de -20 à 20, c'est à dire que la caméra sera (statistiquement parlant) autant en retard qu'en avance.
Nous allons donc utiliser la valeur "tendance" pour faire varier ça.
Ca va pas mal ressembler à la façon dont on a gérer le néon.
Quand tendance=1, la caméra sera toujours en avance.
Quand tendance=-1, la caméra sera toujours en retard.

si on le traduit pour le wiggle, ça donne ça :
tendance=-1 : le wiggle ira de -20 à 0 (avec un milieu à 10 donc)
tendance=0 : le wiggle ira de -20 à 20 (avec un milieu à 0 donc)
tendance=1 : le wiggle ira de 0 à 20 (avec un milieu à -10 donc)

Ecrivons donc cette amplitude qui peut aller de 20 à 40 selon les cas :


ampF=linear(Math.abs(tendance),0,1,amp,amp/2);

Voilà, on a bien ce qu'on voulait.
Maintenant, on doit créer la valeur final en décalant le centre du wiggle entre -10 et 10:

W=tendance*(amp/2)+wiggle(.2,ampF);

Ainsi, on transforme tendance pour qu'il varie de -10 à 10.
La dernière ligne, on transforme le nombre d'image en seconde :

d=thisComp.frameDuration*W;

Voilà, on a créé notre décalage en seconde.
Maintenant, écrivons l'expression pour la position de ce même calque (on est toujours dans "target cam" je vous rappelle):
p=thisComp.layer("target").transform.position;
d=effect("decalage")("Curseur");
p.valueAtTime(time+d);

J'explique même pas, vous connaissez par cœur tout ça. Juste une petite précision quand même.
Là j'ai écrit
time+d car c'est la valeur de tendance (de -1 à 1) qui va définir le retard ou l'avance.
-1, et le calque sera toujours en retard. 1, et le calque sera toujours en avance. Vous pouvez aussi mettre -10 ou 456, ça ne change rien, la fonction linear écrête les résultats.

Bref, on a bien notre calque "target cam" qui suit la même trajectoire que la cible, parfois en avance, parfois en retard (ça dépend de la valeur de tendance).

Occupons de la caméra à présent.
Nous allons comprendre pourquoi nous n'avons pas écrit cette expression directement dans la caméra.
Certes notre caméraman va être en avance ou en retard, mais il paraît fortement improbable que sa caméra suive exactement le trajet de l'objet.
Nous allons donc utiliser une fonction pour altérer cette trajectoire, et plus exactement, l'adoucir.

Nous allons utiliser la fonction smooth(a,b).
a est la durée sur laquelle un adoucissement va être effectué. Plus la durée sera longue, plus les creux et les bosses seront mélangés.
b Correspond à la puissance du smooth. Gardez comme règle de toujours utiliser une valeur impaire (C'est comme ça, discutez pas).

Sauf qu'il y a un petit problème...
On pourrait se dire qu'écrire ceci fonctionnerait :

P=thisComp.layer("target cam").transform.position;
P.smooth(1,5)

Et bien non, ça ne marchera pas !
Je vous explique pourquoi.
Les expressions dans After Effect ont leurs limites, et notamment une très importante:
Elles n'ont aucune mémoire. Vous ne pouvez pas enregistrer dans la mémoire d'AE une valeur qu'on va venir chercher à chaque image, ou bien faire que cette valeur augmente de n à chaque image (il y a en fait une technique pour faire ça, mais c'est un systeme D où AE recalcule tout depuis le début à chaque image).
Le problème est que se le smooth va faire une moyenne des valeurs, par exemple sur 1 seconde, il va aller voir les valeurs sur 1/2 seconde avant, et 1/2 seconde après. Sauf que voilà, il ne peut pas connaître les valeurs du futur puisqu'elles n'ont pas encore été calculée.

Nous devons donc passer par une étape supplémentaire.
Ecrivons donc juste ceci :
P=thisComp.layer("target cam").transform.position;

La caméra a donc exactement le même mouvement que "target cam"
A présent, en ayant la variable "point ciblé" sélectionnée, allez dans Animation, assistant d'image clé, convertir l'expression en image clés.

After va créer une clef par image calculées par l'expression, et désactiver cette dernière.

A présent, effacez l'expression et remplacez là par

smooth(1,5)

Et voilà !
Donc à chaque fois que vous faite une modification dans l'objet "target cam", vous devez reconnecter la caméra en remettant :
P=thisComp.layer("target cam").transform.position;

Refaire le coup de "Animation machin bidule), et remettre smooth(a,b).

Ne vous plaignez pas, ça prend 5 secondes.

Voilà c'est fini, vous avez votre belle caméra qui fait un beau mouvement.
Encore une article bien long, mais au final, il y a très peu de ligne à écrire.



Ce système est largement améliorable.
Par exemple, on peut imaginer que le caméraman dézoome quand la cible est trop loin de sa caméra.
Autre finesse, si l'objet se déplace essentiellement horizontalement, on voudra gérer de manière séparer X et Y.

Peut être pour un prochain article.

Aucun commentaire:

Enregistrer un commentaire