Aide pour After Effect, techniques, expressions.

samedi 31 janvier 2009

diaporama alpha turbo prime 2

Ouais je sais, ça devait arriver plus tôt, mais comme pas eu le temps, bah me revoilà.
Alors alors, on prend les mêmes, et on recommence. Ce coup ci, on veut que tous nos calques aient la même échelle. Mais plutôt que de choisir la largeur ou la longueur et donc avoir des problèmes avec les calques verticaux et horizontaux, on va faire en sorte que tous les calques soient visuellement de la même taille.
Nous allons donc accorder leur diapason non pas sur leur dimension sur x ou y, mais sur leur aire.
Allons y:

La base est la même que pour le post précédent.
Créez un Null "controle", avec un paramètre glissière "aire"
Pour cette valeur de "aire", mettons pour le moment 80.

Créez un solide de 350x100 (par exemple), ouvrez lui son échelle.

La fin sera la même que l'autre post, puisque la finalité est la même, à savoir imposer une taille en pixel à un calque sans se préoccuper de sa taille initiale.

On commence facile :

A=Math.abs ( thisComp.layer("controle").effect("aire")("Curseur") ) *1000;

A vaudra donc la valeur positive de "aire". Petit rappel du post regroupant la plupart des "Math.", Math.abs renvoie la valeur absolue (donc positive).
Et multiplié par 1000. Pourquoi par 1000 ? Et bien imaginons un calque "normal" d'une taille de 600*500. Son aire vaut donc 300 000. Donc on se rend compte que l'aire, c'est vite grand (tout est relatif), et qu'on aura souvent des multiples de 1000. Donc plutôt que d'écrire 300 000 dans "aire", autant écrire 300, c'est plus claire.
Ça, ç'est fait.
Ensuite, il faut que l'on définisse le rapport hauteur/largeur de notre calque:

R=width/height; (le rapport largeur/hauteur ici donc)
Donc si notre calque est large, R vaudra un chiffre supérieur à 1, s'il est carré, R=1, et s'il est étroit, 0 < R < 1

Comme l'échelle est uniforme, il suffit de trouver x par exemple.
Trouvons donc la formule qui donne x en fonction de R, avec l'aire A donnée.

x * y = A
x / y = R donc y = x / R
donc
x * ( x / R ) = A
x² / R = A
x² = A * R
x = racine carrée de A * R

et voilà, ça donne ça dans AE:

W=Math.pow ( A*R , 0.5 );

Même chose, petit rapel, Math.pow(a,b) donne a à la puissance b.
Et quand la puissance vaut 0.5, il s'agit de la racine carrée.
J'aurais également pu écrire ça:

W=Math.SQRT1_2(A*R);

Ceux qui se rappelle quelques trucs en maths comprennent donc pourquoi on a rajouté "Math.abs" à la valeur de aire. Sinon, on aurait pu avoir une valeur négative à l'intérieur de la racine carrée; et j'ai vu des after effect se desinstaller tout seul pour moins que ça...
Un moyen mémotechnique :
racine carrée de -1 = caca.


Et maintenant qu'on a la valeur en x, hop :

s=(100/width)*W;

Exactement la même chose que pour l'autre post.

la dernière ligne :

[s,s]

Et voilà. Avec cette expression ( je faix exprès de pas tout mettre à la fin, comme ça, hop, pas de copier coller des fénéants, du moins pas d'un coup, c'est déjà ça de gagner), tous vos calques auront la même aire, qu'importe leur taille ou leur forme.

Mais, mais, mais.... Comme vous devez le savoir, visuellement, moins un calque est carré, moins il parait grand à surface équivalente. Donc on a tendance à agrandir les calques étroits, pour qu'ils paraissent aussi important que les plus carrés.
Il faut donc ajouter une correction à tout ça.
Et là, c'est un peu moins drole, je dois l'avouer.

Alors alors...
Nous devons créer une valeur qui va nous dire à quel point un calque n'est pas carré.
Je propose ça :
calque carré = 1
moins un calque est carré, plus la valeur tend vers 0.
Comment on fait ça ? mmh?

Tout d'abord, rajoutez un paramètre glissière à votre Null controle, et appelez le "correction"
Après la 1ere ligne "A=
..."
rajoutez ça :

C=thisComp.layer("controle").effect("correction")("Curseur");

Ensuite, après votre ligne "R=machin" :

rect=R;
if (R>1) {rect=1/R}

Alors kénécé...
rect=R, ça c'est facile, on demande que rect soit égale à R, j'ai le droit.

if (R>1) {rect=1/R} Je crois pas que l'on ait dejà vu le "if"
C'est assez simple :
if (condition) {fais ça}
Notez bien les parenthèses pour la condition, et les accolades pour l'opération à effectuer.
Donc là, si R est plus grand que 1 (donc si notre calque est large) rect vaut 1/R.

Pourquoi je fais ça ?
Et bien parce que l'on veut avoir une valeur qui dit à quel point notre calque n'est pas rectangulaire. Et nous voulons la meme valeur pour les calques larges ET étroits.
Or pour un calque de 400x40, R vaut donc 10.
Et rappelez vous, nous voulons une valeur entre 0 et 1.
Donc si on a un calque étroit, R vaut entre 0 et 1, logique. Et si R=5 à cause d'un calque large, et bien on change la valeur pour 1/R, qui sera forcément entre 0 et 1.
Ainsi, un calque de 400x40 aura un valeur de 0.1, de même qu'un calque de 40x400.
C'est bien ce que l'on voulait faire, trouver une valeur de rectanglitude (et pourquoi pas d'abord), sans se préoccuper de savoir s'il est horizontal ou vertical.

ensuite, on n'a plus qu'à créer la valeur de correction à appliquer à la formule finale :
Nous allons donc utiliser la valeur C, celle de "correction" du Null de controle. En effet, vous pourrez ainsi modifier le taux de correction, puisque ce dernier est visuel, et donc subjectif/circonstantiel:

correction=linear ( rect , 0 , 1 , 1+C/100 , 1 );

vous connaissez dejà linéaire, je ne réexplique pas.
Donc, ici, quand rect=0, correction vaut 1+C/100
quand rect vaut=1, correction vaut 1.

la dernière ligne :

s=(100/width)*W*correction;

[s,s]

La seule différence est le rajout de *correction. Et là, vous comprenez parfaitement la ligne "linear" : Quand rect vaut 1, donc que le calque est carré, correction vaut 1, donc il ne modifie pas la formule.
Quand rect est différent de 1, donc entre 0 et 1, il tend vers 1+C/100.
J'ai divisé par 100 la valeur du paramètre glissère, car étant donné que correction va multiplier l'ensemble, il faut rester dans des petits chiffres.
Sinon, si on met 120 dans le paramètre glissère, on va avoir une échelle corrigée par un joli *121, et c'est pas joli.

Et voilà. Vous pouvez tester, vous verrez qu'en faisant varier la valeur de correction dans le Null de controle, les calques les plus étroits/larges grandissent plus que les plus carrés.

et voilà.

bon aller...l'expression en entier :

A=Math.abs ( thisComp.layer("controle").effect("aire")("Curseur") ) *1000;
C=thisComp.layer("controle").effect("correction")("Curseur");
R=width/height;

rect=R;
if (R>1) {rect=1/R}

correction=linear(rect,0,1,1+C/100,1);

W=Math.pow ( A*R, .5 );
s=(100/width)*W
*correction;

[s,s]

mercredi 28 janvier 2009

diaporama

Alors voilà, vous devez faire un diaporama, avec par exemple, plein de photos. On vous a filé les photos, comme d'hab, les qualités sont très variables, mais surtout, les tailles sont toutes différentes. Y'a des trucs en 400x300, d'autres en 1200x600, etc. (pour le moment, je ne parle pas de rapport hauteur/largeur, mais bien de nombre de pixels).

Et pour votre diaporama, qu'importe son type, il faut normaliser un peu tout ça. Alors oui, on pourrait modifier toutes les photos dans photoshop, en réduire certaines, en agrandir d''autres..C'est pas l'idéal, et pas très malléable.

Voilà donc comment faire en sorte que ça soit after qui gère tout :
On veut que toutes les photos soient affichées à la même taille dans la composition d'after effect. Donc en gros, plus le fichier est grand, plus l'échelle sera petite.
La manip est la suivante : On réduit le calque à la taille d'un solide de 1x1 pixels, puis on va l'agrandir à la taille que l'on veut.
Comment réduire à 1x1 des calques qui sont tous différents avec une même expression ?
Imaginons dans notre cas que nous voulons que les largeurs des photos soient toutes les mêmes, ici d'une valeur de 250 pixels :
(100 / largeur ) * 250
En divisant 100 (l'échelle 1:1 d'after) par la valeur de la largeur du calque, on le réduit à son unité en quelque sorte. Et en le multipliant par 250, on lui donne la valeur que l'on veut.

Un exemple intuitif : Imaginons un calque qui fasse 100 pixels de large :
(100 / 100)*250
On voit bien que 100/100 nous donne 1, donc 250*1=250.
Si notre calque de base faisait 500 (donc 2 fois la taille finale):
(100/500)=0.2 , 0.2*250=50
le calque sera donc à 50%, 50% de 500, ça fait bien 250.

Bon, après avoir rejoint Einstein sur ce coup là, voyons l'expression.
Créez un Null que vous appelez "controle", et ajouter un paramètre glissière que vous appelez "taille"

Et écrivez ceci pour l'échelle de chaque calque:

t=thisComp.layer("controle").effect("taille")("Curseur");
s=(100 / width)*t ;
[s,s]

Je me souviens plus si j'en ai dejà parlé, mais "width", c'est évidemment la valeur de la largeur du calque.
Ainsi, avec le parametre glissiere "taille", vous pouvez définir la largeur cible de tous les calques.
Si vous préférez gérer la hauteur, remplacez "width" par "height".

Et là, vous allez me dire : ouais c'est cool ton truc, mais les images les plus rectangulaires font franchement petites à coté des images plus carré. Et si on a des images verticales ET horizonales, on peut pas vraiment choisir si on normalise la largeur et la hauteur !!

Et vous aurez raison. C'est pour cela que le prochain post, on verra comment faire pour que n'importe quel calque, qu'importe son rapport hauteur/largeur, soit harmonieux avec tous les autres calques.
Mais c'est un poil plus compliqué quand meme... faut pas déconner.
Ca sera pour demain ! C'est ça qui est chouette.

Bonne soirée

mardi 6 janvier 2009

ombre moi ce shine

Et hop, comme promis, un exemple concret du calage d'un calque 2d sur une position 3d.
Et même 2 tiens, je suis en forme. Ouais c'est surtout parce que le 1er exemple est super simple.
Le calage d'un lens flare sur une lampe 3d.
Alors ouais, j'ai fait un truc super beau, j'ai fait ça:














On voit bien que le lens flare est accroché à la lumière.
La position du lens flare est une position 2d.
J'ai donc écrit ça dans la position du lens flare:

target=thisComp.layer("Lumière 1");
target.toComp([0,0])


Et voilà.
Une autre exemple un peu plus complexe.
Imaginons une scène avec une lampe, et des calques 3d. L'environnement est plein de poussière, les calques 3d laissent donc derrière eux une trainée d'ombre dans la poussière.
Une image vaut mieux que plein de mots, hop :














Derrière ce message universel et positif ce cache une plastique superbe, un gout certain...Bref, on s'en fout, on va voir comment faire ça.
La scène est simple à mettre en place:
Une lumière dans le fond, un texte 3d devant (soyez inspirés), une camera (une jolie).
Créez un calque 2d dans le fond, appelez le "fond" tiens, appliquez un dégradé circulaire. Mettez le centre du dégradé en gris clair, et l'autre en noir.
Pour la position du point blanc, c'est tout bête:

target=thisComp.layer('Lumière01");
target.toComp([0,0,0]);

Pour le point noir :

target=thisComp.layer('Lumière01");
target.toComp([0,0,0]) + value ;

Comme ça, le point noir bouge aussi, et vous pouvez le déplacer pour l'éloigner du point blanc à votre guise©.

On a donc simulé notre lumière du fond.
A présent, il faut que l'on simule la trainée de l'ombre, qui donnera l'impression qu'il y a de la poussière, ou un sachet de drogue bêtement gâché.
Pour cela, j'ai utilisé l'effet Shine de Trapcode. Il y a d'autre éditeur qui font un effet équivalent, je n'ai pas les noms en tête. Si vous n'avez rien de tout ça, vous pouvez utilisé CC radial blur avec l option straight zoom, mais le calcul est très long, et c'est moins bien.

Donc, pour la valeur de la position du centre de l'effet Shine :

target=thisComp.layer('Lumière01");
target.toComp([0,0,0]);

Comme pour tout le monde ya pas de raison.
Dans colorize, mettez None, ou bien sur 1 couleur avec du noir donc, régler la taille de la trainée, et vous pouvez rajouter un effet "niveau alpha" pour augmenter la densité de l'effet.

Et voilà !!

Certains auront remarqué que dans ma vidéo, il y a un lens flare accroché à la lumière, et que ce dernier diminue quand il va bientôt etre caché par les lettres, puis s'éteind, pour reprendre de plus belle quand la lumière réapparait. Comme dans la vraie vie.

Et bah ça, ça sera pour le prochain post.

lundi 5 janvier 2009

toComp from space

Derrière ce titre digne des plus grandes fresques spacio-capitalistes se cache ni plus ni moins qu'un banal post sur un blog douteux.
Mais ça va être chouette, donc tout va bien.

votre nouvelle envie du moment ? Faire qu'un calque 2d soit toujours à la même position qu'un calque 3d. Qu'est ce que ça veut dire ? Et bien imaginer qu'un petit solide 3d se balade dans votre scène, et qu'un autre petit calque 2d le colle "visuellement", un peu comme une mire sur un avion (brrr).
Il n'y a en effet aucun autre moyen de faire cela, étant donné que la camera peut également bouger, sans que l'objet 3d ne se déplace. Quand la camera bouge, la position du calque 3d, par rapport à la composition, change.
Et bien c'est tout pareil que tout à l heure, sauf que pour le
target=
on accroche un objet 3d.
C'est tout...
Attention, si vous mettez :
target3d.toComp([0,0]),
votre calque 2d sera collé en haut à gauche du calque 3d. Donc si vous voulez qu'il soit au milieu, il faudra mettre target3d.toComp([50,50]) si votre calque 3d fait 100 sur 100. C'est simple, si vous n'avez pas touché au point d'ancrage du calque 3d, il sera au milieu, et vous donnera donc les bonnes valeurs à mettre.
Si votre calque 2d doit être accroché un une lumière d'after, mettez [0,0].
J'illustrerai ce post avec des jolis GIF animés plus tard, pour faire gagner en magie cette page pleine de mot.
On verra un exemple concret par la suite, promis.

toComp

Suite des aventures de notre nouvel ami, le référentiel.
Nous avons vu comment transformer des coordonnées de la composition vers un calque.
Voyons maintenant l'inverse, c'est à dire comment transformer les coordonnées d'un calque vers la composition.
C'est assez simple, on va utiliser ceci:
toComp.
Voilà comment on procède :
Créez un calque.
Créez une autre calque, plus petit s'il vous plait.
Dans ce dernier, écrivez :
target=
et accrochez à l'autre calque. Pas à sa position ou autre, non non, au calque.
Vous aurez donc un tuc du genre :
target=thisComp.layer("solide 1");

Ensuite, ecrivez ceci:
target.toComp([0,0])
target est ici le référentiel demandé. [0,0] est la position que l'on souhaite ciblée, à partir du calque. Comme vous pouvez l'observer, le petit calque se place sur le coin supérieur gauche de l'autre calque, puisque [0,0] correspond au coin supérieur gauche du grand calque.
C'est bien l'exact inverse de fromComp.
On comprend ainsi qu'avec notre exemple des 4 ronds rouge qui controlent l'effet quatre coins du calque jaune vu précédemment, avec toComp, on peut avoir la meme interaction, mais à l'envers : l'effet quatre coins fera bouger chaque rond rouge.

Et voilà.

samedi 3 janvier 2009

pourquoi tant de haine?...

Mais...Finalement...Pourquoi se compliquer la vie avec toutes ces expressions ?
Elles sont parfois obligatoires, et parfois tellement pratiques que faire autrement paraitrait idiot.

Et parfois..On doute....Est ce que je me fais chichi à installer tout mon système d'expressions, et après je suis tranquille pour tous les futurs réglages, ou bien je joue le fainéant, et je fais tout avec des clefs, même si ça me prend beaucoup plus de temps, j'utilise moins mon cerveau, et ça me permet de suivre NRJ12 sur mon écran de gauche sans broncher.

Chacun fait ce qu'il veut, bien entendu, mais voilà une petite règle objective qui permet de trancher (et couper NRJ12 par la même occasion, merci):

-Lorsqu'il s'agit d'un automatisme du à une interaction, utilisez les expressions.
Par exemple, plus mon calque est loin de la camera, plus il est transparent (mais si mais si, vous savez le faire). Il s'agit d'une interaction, aucun intérêt de le faire avec des clefs.

-Plusieurs calques vont surement subir dans le futur une ou des modifications équivalentes. Utilisez les clefs si possible. Par exemple, on a une série de calques qui vont apparaitre à différents moments de la composition. Ils doivent tous apparaitre avec un fondu d'une même durée. Plutôt que créer deux clefs (0% - 100% par ex) de transparence, et de devoir rapprocher ou éloigner la 2eme clef de tous les calques en même temps pour changer le temps du fondu, préférez ceci :
Créez un Null avec un paramètre glissière, et mettez y vos deux clefs 0-100% comme vous le souhaiter.
Installez tous vos calques en escalier sur la timeline, pour qu'ils commencent là où leur fondu doit commencer.
Écrivez ceci dans leur opacité :
t=thisComp.layer("Null").effet("paramètre glissière")("curseur");
t.valueAtTime(time-inPoint)

inPoint est égal à la valeur du temps du début du calque, donc (time-inPoint) permet que le temps 0 commence au début du calque.

Ainsi, chaque calque aura son fondu qui commencera à son début, en prenant en compte la façon dont vous avez animé vos valeurs du Null, y compris dans la courbe d'accélération et de décélération. Impossible d'avoir la même courbe pour tous les calques si c'était fait à la main, à part avec un (honteux) copier coller sur 200 calques.

L'expérience vous permettra de réfléchir 2 sec avant de vous lancer dans une animation.
L'exemple ci dessus à l'air compliqué pour quelque chose d'aussi simple, mais c'est en fait simple, rapide et puissant.

c'est tout pour le moment.

vendredi 2 janvier 2009

les référentiels / bonne année

Faisons d'une pierre deux coups. Donc bonne année.*
Mon âme d'humaniste a parlé, passons aux choses sérieuses.

C'est quoi donc un référentiel ? Einstein l'explique assez bien dans sa théorie de la relativité général et restreinte, Galilée aussi avait pas été trop con sur ce coup là.
Pour AE, on va simplifier la donne;
un référentiel est une base, souvent spatiale dans AE, de laquelle découle d'autres valeurs.
On pourrait dire qu'il s'agit du point [0,0]. Et comme dans AE, chaque calque voit [0,0] à sa porte, il faut que tout ce petit monde puisse communiquer.
L'image suivante va poser la problématique:



















le point A a pour coordonnées [200,100].
le point B a pour coordonnées [400,225].
Jusque là, tout va bien.
SAUF que pour le calque rouge, bah le point A a pour coordonnées [0,0] et B [200,125].
Pour le point B, A est en [-200,-125].

Certains me diront "oui bah moi je m'en fous, j'ai jamais eu ce genre de probleme, donc pourquoi se poser ce genre de question?"
Et bien car il y a quelques cas où vous allez vous dire "crotte, ça marche pas le truc que je veux faire" (je m'adapte à votre langage)
Prenons un exemple simplissime:
Créez un solide plus petit que la composition (ça arrive à tout le monde), et appliquez lui l'effet
"quatre coins" dans "déformation" des effets. (corner pin en anglais)
C'est un effet tres connu et tres utile, qui permet de déformer une image en déplaçant chaque coin.
Et bien vous aller vous rentre compte que les coordonnées de chaque point a pour référentiel non pas la composition, mais le calque. Et c'est bien logique. Sinon, dès que l'on déplacerait le calque, les valeurs changeraient.
Ainsi, le point en haut à gauche est à [0,0], etc.
Et c'est là que se pose le premier probleme. Imaginons que l'on veuille créer ceci :









On veut que le rectangle jaune se déforme en suivant chaque rond rouge. Mais voilà le souci, avec le modificateur quatre coin, on a un point en haut à gauche en [0,0], alors que le rond rouge correspondant doit avoir des coordonnées d'environ [100,100].
Si vous accrochez la valeur de position du rond rouge au coin supérieur, vous n'aurez pas du tout ce que vous voulez.
C'est là qu'intervient une suite de nouveaux mots:

fromComp( [x,y] ) : transforme [x,y] pour qu'il concorde avec le référentiel du calque dans lequel on écrit ça.

Ceci nous donne la solution au probleme que l'on vient de voir.
Voilà ce que l'on doit écrire en français:
"pour le coin supérieur gauche, transforme la position du rond rouge en changeant de référentiel. Pour nouveau référentiel, prend le coin supérieur gauche du calque en tant que [0,0]

imaginons que le rond rouge s'appelle "HG" (haut gauche)
voilà ce qu'on écrit pour la position du coin supérieur gauche de l'effet quatre coin:

fromComp ( thisComp.layer("HG").position)

et faire pareil avec chaque coin.
Et voilà !
Vous savez changer de référentiel. Cela peut s'appliquer dans de nombreux cas. La plupart des effets qui demande une position (effet de dégradé par exemple) utilise le système de coordonnées interne au calque, pas celui de la composition.
Meme principe, avec l'effet "dégradé 4 couleurs"














Le seul cas où on a pas besoin de tout ça, c'est lorsque le calque fait la même taille que la composition, et est centré. Là, évidemment, les deux référentiels sont confondus, donc ça va.

Dans le prochain post, on verra comment faire pour qu'un calque 2d récupère la position d'un calque 3d, tout en restant en 2d.
Ouais ouais c'est possible, et c'est encore une histoire de référentiel.

*phrase non contractuelle.