
          La Methode pour faire du bump sur une image 2D
                (comme dans Orion, de Flower Corp.)

                (c) Mai 1996 Phar /Flower Corp
                contact : souiki@fiifo.u-psud.fr

Si vous avez des questions concernant le present document, n'hesitez pas a
m'envoyer un mail, ou a me parler sur IRC sur #demofr


I Presentation
--------------

  Dans notre premiere Demo, intitulee Orion, presentee a la Saturne 96, le
titre a visiblement ete apprecie par beaucoup de personnes qui ont trouve
l'effet interessant.

  L'effet dont il s'agit, consiste a deplacer une lumiere sur une image, et
a voir comme resultat le relief de l'image : c'est un effet de bump.
Ainsi, suivant que la lumiere se trouve a droite ou a gauche d'un point,
la couleur de celui-ci sera differente.

  Ce n'est pas la premiere fois que l'on voit cet effet dans une demo, puis-
que Jmagic ou Dune l'ont deja programme, mais de facon legerement differente.



II La programmation
-------------------

A) L'image de base
------------------

  Cet effet repose entierement sur la creation d'une image, qui trace des
courbes de niveau : un point noir sera a une faible altitude, alors qu'un
point blanc sera eleve.

  Une image valide n'est cependant pas dure a construire : il suffit de prendre
un plasma comme arriere plan, et de rajouter par dessus un texte ecrit en
blanc si l'on veut avoir l'impression qu'il "sort" du fond, ou en noir, si
l'on veut avoir l'impression qu'il "entre" dedans. Il ne reste alors plus
qu'a antialiaser les bords du texte, pour avoir un effet plus cool.

  C'est cette methode que j'ai applique pour le titre d'Orion, et elle a ete
tres simple a mettre en oeuvre (5 minutes pour faire les 3 images)



B) Le principe du Bump
----------------------

Une fois que nous avons notre image, il devient assez facile de voir ce que
l'on desire : pour chaque point, on va calculer sa normale N (nx,ny),
et l'on va comparer cette normale avec le vecteur lumiere L (lx,ly).

On va donc pour chaque point de l'ecran, avoir un couple L(lx,ly) et N(nx,ny)
Voyons le calcul de L. Soit P(i,j) la position d'un point de l'ecran, et
C(cx,cy) la position du centre de luminosite.

Lx=i-cx
Ly=j-cy

On va maintenant s'amuser avec L et N, pour en tirer une luminosite.
Le raisonnement se fait parallelement en X et en Y, je vais donc l'expliquer
pour les X :

On va commencer par calculer Nx :
Nx=image[x+y*320+1]-image[x+y*320-1];
Donc, si Nx est POSITIF, c'est que le point de droite est plus haut que le
point de gauche, donc, que la normale est orientee vers la GAUCHE!!
Eh oui! C'est inverse!


Nx, n'est en fait pas une vraie normale (on se trimbale pas avec les cosinus)
C'est une valeur qui indique l'orientation du point.
Si nx=0   , les deux points ont la meme couleur.
            la normale va vers le haut.
Si nx=-256, le point de gauche vaut 256, et le point de droite vaut 0 :
            la normale est a droite
   nx=256 , la normale est a gauche.


Regardons maintenant du cote de la lumiere :
Mettons que le point C se trouve a gauche du point P. Au point P, la lumire
sera donc oriente vers la droite. On aura donc :
Lx=i-cx, et comme cx<i, lx>0 , non ?
Donc, quand la lumiere va vers la DROITE, lx est POSITIF (c'est pas comme les
normales)

Reprenons :

L'orientation est :
     Positif Negatif
Lx   Droite  Gauche
Nx   Gauche  Droite



On a donc maintenant Lx et Nx, et on sait ce qu'ils representent.
Une question subsiste neanmoins : pourquoi se prendre la tete avec ces
histoires de signe?
Eh bien c'est tout simple, c'est VOULU! eh oui. Grace a cette methode, on a
une technique tres simple pour connaitre la luminosite d'un point.

En effet, si l'on regarde le principe du bump :
Plus un point sera frappe par la lumiere, plus il sera lumineux. Cela veut
dire: si un point est oriente vers la droite, il devra etre eclaire de la
droite pour etre lumineux. Si il est eclaire par en haut, il sera gris, et
si il est eclaire de la gauche, il sera sombre.
En fait, un point oriente vers la droite (Nx<0) doit avoir un vecteur lumiere
qui va vers la gauche (Lx<0) : C'est bizarre, mais Lx et Nx ont le meme signe!
Cela se formalise tres bien :

 ---------------------------------------------------------------
| Lx et Nx doivent avoit des valeurs les plus proches possibles |
 ---------------------------------------------------------------

Plus les valeurs seront dissemblables, plus le point sera sombre. C'est aussi
simple que cela!

On va donc calculer
x=Abs (Lx-Nx), pour avoir "l'indice de difference".
Plus x sera faible, plus le point sera lumineux. Et si par hasard, on calcule:
coul = 127-X
coul = 127 - Abs (Lx-Nx)  et si coul<0, coul=0
Et voila, on vient de calculer du bump en X.
car coul contient maintenant l'intensite lumineuse.

Il ne reste plus qu'a faire pareil en Y, et on a nos deux composantes.
Pour les assembler, une simple multiplication suffit:
coul=coulX*coulY*4/256


Et voilou.
Il ne vous reste plus qu'a lire le code source pour tout revoir depuis
le debut. Le principe est simple, mais encore faut-il le comprendre.

