Aide pour After Effect, techniques, expressions.

vendredi 15 janvier 2010

éclairage volumétrique anisotropique

Bonjour à tous,

ça fait un bail, je vous l'accorde, mais comme je n'avais pas écrit de nouvelles expressions, je n'allais pas venir et raconter rien du tout.

Quand j'ai un problème technique dans After Effect, je cherche une solution, et quand la solution contient des expressions, ça vient logiquement s'échouer ici.
C'est le cas aujourd'hui, j'ai essayé de corriger une lacune du plugin Lux de Trapcode.

Ce plugin relavement connu est très pratique, puisqu'il vous permet de simuler un éclairage volumétrique, à savoir que la lumière soit filtrée par les particules dans l'air.

Vous trouverez tous les renseignements ici :
Trapcode Lux

Peut être existe-il d'autres éditeurs qui proposent un effet équivalent, mais je n'en connais pas d'autre.
En général, j'essaye d'éviter de parler de plugin, car ça ne concerne pas tout le monde, mais celui ci est assez connu.
Venons en au fait :
Le "défaut" de Lux (qui sera je l'espère corrigé dans un théorique 2.0 ?....) est que la puissance n'est que fonction de la puissance de la lampe, et non de l'angle de la lampe avec la caméra.

avec Lux :













avec Lux+saucisse:












Et oui, quand vous êtes dans une ambiance poussiéreuse, le faisceau filtré par les particules est beaucoup plus puissant (pour vous) quand la lumière est dans votre direction.

La raison en est simple, il faut considérer la poussière comme un volume à part entière, comme de la cire par exemple. La cire, ça n'est pas vraiment transparent, mais la lumière passe quand même à l'intérieur. Elle se diffuse même.
C'est cette diffusion qui nous intéresse, car elle n'est pas égale dans toutes les directions.
Envoyez un faisceau laser vers de la cire, la lumière va se diffuser, mais avec une nette préférence pour la direction initiale de la lumière.

C'est la même chose avec la poussière.

C'est ce qu'on appelle une diffusion anisotropique, par opposition à isotropique, qui veut dire "égale dans toutes les directions".

Bref, tout ce blabla pour dire qu'on va faire en sorte que la puissance de la lumière (de Lux) soit fonction de l'angle de la lumière avec la caméra.

Ça va pas être très compliqué, alors allons y.
Voyons ce petit schéma :

















Nous avons donc une caméra (dont la source s'appelle "ca") et une lumière dont nous appelleront la source "la" et la cible "lb")
En gros, la lumière sera au plus fort quand elle sera exactement dans l'axe de la camera, c'est à dire que le vecteur (ca,la) sera dans le meme axe que le vecteur (la,lb), mais dans la direction opposée.

Est-ce aussi simple que ça cela ?
On pourrait en effet créer un modèle beaucoup plus compliqué, en prenant en compte par exemple l'angle du cône de la lumière. En effet, plus le cône est large, plus l'intensité restera forte sur une plage angulaire importante. Cela mériterait en effet d'entrer dans l'équation.
Mais nous allons faire sans (et également sans la focale de la camera), et nous verrons à la fin pourquoi. Ne vous inquiétez pas, il ne s'agit en rien d'une quelconque paresse.

Commencez par créer votre petite scène, avec votre caméra, votre spot, et votre calque Lux.
Ensuite, rajoutez 3 paramètres glissière au même calque Lux :
-falloff
-val min
-val max

Ensuite, revenez dans l'effet Lux, aller dans spot Lights, et créez une expression pour "Intensity"

Commençons par créer nos variables :

falloff=effect("falloff")("Curseur");
min=effect("val min")("Curseur");
max=effect("val max")("Curseur");

Ensuite :

ca=thisComp.layer("Caméra 1").transform.position;
la=thisComp.layer("Lumière 1").transform.position;
lb=thisComp.layer("Lumière 1").transform.pointOfInterest;
lv=sub(lb,la);
lvn=normalize(lv);

Pas grand chose à expliquer à des gens aussi fort que vous, on définit la position de la caméra, la position de la lampe, puis le vecteur qui donne la direction de la lampe.
Pour rappelle, quand on veut créer un vecteur AB, on écrit sub(B,A);
Je ne me souviens plus si on a déjà vu le normalize, alors dans le doute, il permet de transformer un vecteur donné(qui je vous rappelle, a 2 composantes : une direction, et une longueur) en un vecteur de même direction, mais de longueur 1. On le normalise quoi....
Pourquoi fait-on ça ? Car nous allons le comparer au vecteur (camera,lampe). Et comme la distance entre la lampe et sa cible peut prendre n'importe quelle valeur et qu'elle n'intervient pas dans le calcul (seul la direction nous intéresse), on normalise.

Vous suivez ? On continue.
Créons le vecteur (camera,lampe):


ca_la=normalize ( sub(la,ca) );

J'aurais pu l'écrire en 2 lignes (une pour la création du vecteur, l'autre pour la normalisation).
Nous avons à présent 2 vecteurs de taille égale à 1, avec chacun une direction différente (à priori)

On comprend donc que si on fait vecteur1+vecteur2, on va obtenir un 3ème vecteur qui aura une taille donnée. C'est la taille de ce vecteur qui va nous dire à quel point les 2 vecteurs ont des directions différentes.
Imaginez que la lampe soit exactement dos à la caméra. Si on additionne les deux vecteurs, comme ils sont dans la même direction, on a donc un 3ème vecteur d'une taille de 2.
Si la lampe est pile poil dans l'axe de la camera, ça fait 1-1=0.
Si les deux vecteurs sont perpendiculaires, on obtient donc un troisième vecteur égale à racine de 2.




Trouvons le vecteur bleu :

delta=add(ca_la,lvn);

On a bien additionné le vecteur qui va de la caméra à la lumière avec le vecteur allant de la lumière à la cible de la lumière. Chaque vecteur est égal à 1, le vecteur bleu varie bien de 0 à 2.
Attention, sur le petit schéma, ne pensez pas que la ligne blanche correspond à l'axe de la caméra, ça n'est pas du tout le cas. Il s'agit bien du vecteur (caméra,lampe).

Revenons à la base, on est en train de régler l'intensité. Il nous faut donc une variable qui va de 0 à 1.
Transformons donc delta qui va de 2 à 0 pour qu'il aille de 0 à 1:

angle=1-length(delta)/2;

C'est maintenant que la finesse se passe. On a bien notre variable qui va de 0 à 1. Il suffit par exemple de multiplier cette valeur par 100, et on a notre effet.
Sauf qu'il nous manque un petit réglage. En effet, on ne peut pas régler la façon dont on va de 0 à 1. Pour le moment, c'est linéaire.
Par exemple, quand la lumière passe de "face" à "profile",on passe de 1 à 1-1.4 (en gros) de façon linéaire, et même chose pour "profile" à "dos".
Sauf que ça n'est pas ce qu'on veut. Quand la lumière est de face, on est à 100%, et plus la lumière s'écarte, plus la puissance baisse vite. La courbe est donc exponentielle.
Il faut donc qu'on casse cette ligne droite qui va de 0 à 1. Pour parler intuitivement, il faut que la courbe ait du mal à arriver à 1, que 1 soit un pic, un roc ou ce que vous voulez.

C'est pour cela qu'on a créé la variable "falloff".

Voici la ligne suivante :

courbe=Math.pow(angle,falloff);

On va donc avoir notre variable qui va de 0 à 1 à la puissance falloff.
Et comme on est entre 0 et 1, on reste entre 0 et 1. Plus falloff est grand, plus la courbe est prononcée, plus l'angle devra être "parfait" pour atteindre 1.
Vous comprenez maintenant la valeur qui défile dans la vidéo, il s'agit de la puissance de la lampe, vous pouvez ainsi voir que la valeur ne commence à augmenter réellement qu'à proximité de l'axe de la caméra.

Voilà pourquoi je n'ai pas créé de variable pour le cone de la lampe ou autre.
Tout se fait avec la variable falloff qui vous permettra de régler votre effet. Plus vous voulez une lumière directionnelle, plus il faudra augmenter la valeur. En gros, vos valeurs iront de 5 à 100, pour vous donnez un ordre de grandeur.

Il ne manque plus que la dernière ligne :

ease(courbe,0,1,min,max)

Voilà, il ne vous reste plus qu'à mettre des valeurs dans val min et val max (comme 10 et 100 par exemple), et le tour est joué.

Voilà, c'était long car je voulais bien expliquer la petite réflexion qui permet d'arriver à ça, car en suite, l'expression est simplissime, on a fait 10 fois pire ensemble.
Si on enlève les lignes de création de variable, il n'y a que 5-6 lignes.


Encore une petite précision tout de même. Vous risquez d'avoir un problème si votre lampe a un parent. En effet, After Effect va modifier les valeurs de position et de point cible en fonction du parent. Le problème vient du fait que pour les expressions, AE récupère les valeurs de chaque variable sans prendre en compte les parents. Vous obtiendrez donc des valeurs erronées.
Je parle de ça car il est assez commun qu'une lampe ait un parent, pour par exemple pouvoir déplacer les deux points de la lampe en même temps.

La solution est de définir la position ainsi :

position=objet.position+parent.position

1 commentaire:

  1. Merci pour ce blog! C génial!
    Merci aussi à Mattrunks pour le lien ;)

    RépondreSupprimer