Aide pour After Effect, techniques, expressions.

mardi 18 mai 2010

accordeon 2



Tout d'abord, cet article est destiné à ceux qui ont lu (et compris) l'article précédent sur l'accordéon, car je m'y réfère.


Voyons à présent la version 2 de l'accordéon, avec un retard sur chaque plaque, dans un sens où dans l'autre.

Imaginez que vous tenez ses plaques dans les mains et que vous lâchiez toutes les plaques sauf la 1ere. Elle vont toutes tomber en paquet, et se défaire en partant du haut, au fur et à mesure que la résistance de la 1ere plaque fasse son effet. Ca c'est le cas où les plaques vont s'ouvrir en partant de la 1ere plaque.
L'autre cas est si vous poser les plaques sur une table, et que vous tirer la dernière plaque. C'est cette dernière qui se dépliera en 1ère, les autres suivants. L'inverse donc.
Nous allons donc prévoir ces 2 possibilités.
Cette option nous impose un changement de méthode.
Dans la version précédente, nous utilisions l'angle de la plaque précédente pour trouver l'angle de la plaque courante. Si nous voulions on retard, il suffirait d'utiliser une phrase du type :

ThisComp.layer(thisLayer,-1).rotationY.valueAtTime(time-d);

Le problème, c'est que l'on veut pouvoir avoir le retard dans un sens où dans l'autre. Cela veut dire que d va donc varier selon le sens, mais de manière compliquée, puisque la 1ère plaque à démarrer ne sera pas la même, et que tout va s'inverser....Vraiment pas pratique.

Nous allons donc utiliser une autre approche, dont vous connaissez la base.
Nous allons utiliser l'index relatif de chaque calque pour connaître sa position dans la liste, et en définir son propre retard.
Nous aurons donc la structure que vous connaissez:

-controle
-plaque 1
-plaque clone 1
-plaque clone 2
-plane clone n
-sol

Commençons par le calque "controle", et voyons ce dont on a besoin en plus:

-random
-angle
-inverse
-sens
-retard
-courbe

Seuls les 3 premiers viennent du 1er accordéon, les 3 autres sont nouveaux.
-sens va nous dire qu'elle est la 1ère plaque à démarrer (la 1ère ou la dernière de la liste). Pour cette valeur, vous pouvez d'ailleurs copier l'effet "inverse", puisqu'on veut également une valeur qui aille de -1 à 1.
-retard sera le retard en nombre d'image entre chaque plaque (environ, vous verrez pourquoi)
-courbe va nous permettre de ne pas avoir un retard linéaire.

Créez donc également votre null "sol" qui sera sous toutes les plaques dans la timeline.

La différence se situera au niveau de la rotation sur Y, l'expression sur la position ne change pas.
Commençons par l'expression de la 1ere plaque, celle qui est différente des autres:

angle=thisComp.layer("controle").effect("angle")("Curseur"); H=thisComp.layer("controle").effect("random")("Curseur");
seedRandom(index,true);
hasard=random(-H,H);
inverse=thisComp.layer("controle").effect("inverse")("Curseur"); sens=thisComp.layer("controle").effect("sens")("Curseur"); nombre=thisComp.layer("sol").index-thisComp.layer("carton_start").index; retard=thisComp.layer("controle").effect("retard (frame)")("Curseur")*thisComp.frameDuration;

Les rouges sont les nouveaux venus.
nombre vaut bien le nombre de plaques.
Nous allons à présent définir la position de cette plaque, selon la valeur de sens.
Elle sera ou en 1ère position, ou en dernière:

pos=0;
if (sens==-1) {pos=nombre};

Quand sens=1 (le "==" est le égal dans le monde des conditions. Le simple "=" enregistre une valeur dans une variable, à ne pas confondre), pos=0, ça sera le 1er calque.
Quand sens=-1, il sera en dernier, pos vaudra nombre+1=le nombre de plaques, car nous avons définit la valeur de nombre -cette plaque.
Bref, la dernière ligne :

(angle.valueAtTime(time-retard*pos)+hasard)*inverse;
Rien de bien compliqué. On comprendra donc que le retard vaudra ou 0, et bien retard*le nombre de plaque, et sera donc bien en dernier.

Passons à présent aux autres plaques, plus compliqué. En effet, ça sera moins binaire (ou 1er ou dernier).

Nous allons créer une variable "retardMax" qui sera égale au retard entre la derniere plaque et la 1ère. Puis, chaque plaque aura une position de 0 à 1 (dans un sens ou dans l'autre justement), et se verra appliqué un retardMax*cette position.
Allons y:

angle=thisComp.layer("controle").effect("angle")("Curseur"); H=thisComp.layer("controle").effect("random")("Curseur");
seedRandom(index,true);
hasard=random(-H,H);
inverse=thisComp.layer("controle").effect("inverse")("Curseur"); nombre=thisComp.layer("sol").index-thisComp.layer("carton_start").index; retardMax=thisComp.layer("controle").effect("retard (frame)")("Curseur")*thisComp.frameDuration*nombre; sens=thisComp.layer("controle").effect("sens")("Curseur"); courbe=thisComp.layer("controle").effect("courbe")("Curseur");
Tout pareil que la 1ère plaque, on a juste rajouté courbe.
Notez également une différence pour le retard. Cette fois-ci, la variable vaut la totalité du retard.

direction=1;
if (thisComp.layer(thisLayer,-1).rotationY<0 0="" color:="" direction="-1}; <br /> <br /><span style=" rgb="">Direction fera en sorte que chaque plaque soit dans le sens opposé à la plaque précédente.

posBase=index-thisComp.layer("carton_start").index+1;
posSens=posBase;

posSens est la valeur qui nous allons utiliser à terme. Quand sens=1, on ne change rien, on garde l'ordre initial.

if (sens==-1) { posSens=nombre-posBase+1};

Quand sens=-1, c'est l'inverse.
Reprenons notre exemple de 5 plaques. Pour la 5ème:
posSens=5-5+1=1
Pour la 4ème:
posSens=5-4+1=2

On est bon, ça marche !

retardN=linear(posSens,1,nombre,0,1);

On applique maintenant la transformation de la valeur pour aller de 0 à 1. Le N de retard vaut pour Normal, car voici la ligne suivante:

retardCourbe=Math.pow(retardN,courbe);

Cela nous permet d'avoir une retard exponentiel ou logarithmique. Dans le calque controle, la valeur de "courbe" ira de 0 à l'infini, mais dans la pratique, on ira pas au delà de 10, ça ne sert à rien.
On se refusera d'ailleurs les valeurs négatives. Pour une puissance, c'est bof. Pour éviter les messages d'erreurs et les désactivations massives d'expressions, nous allons empêcher "courbe" de prendre des valeurs négatives.
Ecrivez ça dans "courbe" du calque de controle :

Math.abs(value)

Ca évitera les désagréments.
Revenons à la rotationY de notre plaque. La dernière ligne:

(angle.valueAtTime(time-retardMax*retardCourbe)+hasard)*inverse*direction;

C'est long, mais pas compliqué :
on multiplie le retardMax par la valeur qui va de 0 à 1. Le tout multiplier par inverse et direction pour le sens des plaques.

Et voilà, c'est terminé.
C'est encore améliorable, car il y a une faiblesse:

Si vous mettez une valeur trop grande dans le random, vous aurez d'une part des calques qui se chevauchent au départ, et on peut également avoir des sautes de plaque qui passe d'un angle positif à un angle négatif, vous comprendrez vite pourquoi.
Donc restez raisonnable !

5 commentaires:

  1. Je pense qu'il y a une petite precision à apporter pour ma part.
    Apparament je suis le seul à avoir fait ton exo :)

    carton_start doit être le nom de la premiere plaque, sinon ca marche pas.

    RépondreSupprimer
  2. Aussi,
    // thisComp.layer("controle").effect("retard (frame)")("Curseur")

    me renvoi à une erreur.
    Je pense que c'est plutot :
    // thisComp.layer("controle").effect("retard")("Curseur")

    je ne comprend pas bien ce que tu as voulu faire avec (frame)

    RépondreSupprimer
  3. Voila un petit ajout pour "mapper" une image sur les plaques. A ajouter sur le remappage temporel.


    posID=index-2;
    frames = 9.9/25
    taillepix=thisComp.layer("controle").effect("largeur_carte")("Curseur");

    nbr_calques=(thisComp.layer("sol").index-thisComp.layer("carton_start").index);
    nbr_troncons=taillepix/thisLayer.width;

    troncon= (taillepix/nbr_troncons)/thisLayer.width;
    cetroncon=(troncon-frames)*posID;



    Pour que ca marche, il faut faire une precomp des plaques et à l'intérieur, animer une deplacement de l'image de la gauche vers la droite.
    J'ai un peu changé les noms des contrôles.
    Le résultat ne marche pas sur la derniere plaque.
    A l'occasion je veux bien un coup de main!.

    RépondreSupprimer
  4. alors alors...
    pour ("retard (frame)"), il ne s'agit pas d'une erreur en soi. Quand j'ai créé l'expression, j'ai appelé mon paramètre glissière "retard (frame)" pour bien me signaler que la valeur est en nombre d'image et non en seconde. Et quand j'ai écrit mon article, j'ai appelé l'effet seulement "retard". Et comme j'ai fait un copier/coller, je n'ai pas rectifier.

    Sinon, pour ton mappage d'image, j'y mettrai le nez plus tard.

    RépondreSupprimer
  5. ok j'ai pigé cette histoire de frame.
    J'ai été confronté a ca, et c'est vrai qu'il faut être vigilant.


    si tu veux regarder de plus près et a la limite en faire un billet, hésite pas.

    http://www.julienbaret.com/clients/demo/Carte.zip

    RépondreSupprimer