TikiWiki CMS/Groupware v1.9.11 -Sirius- © 2002–2008 par la communauté Tiki Sep 08, 2010 [01:02]
CodeFR
Pin ups
thumbnail
Juillet - Août 2009
Menu [cacher]
  Wiki
  Blogues
  Forums
  QCMs
Mégaphone
hixcod, 12:10, Jan 09, 2010: Happy New year !
MooZ, 09:41, Jan 05, 2010: Bonne année! (erm...)
MooZ, 13:51, Jan 05, 2009: Bonne année!
MooZ, 07:19, Jan 04, 2008: Diantre! Je me suis fait doublé moi aussi. Bonne année quand même (et il faut que je trouve une pinup).
Axioplase, 15:39, Jan 03, 2008: Merde, Froggy m'a devancé sur 2008 !
Froggy, 22:21, Jan 01, 2008: Super mega cool
MooZ, 12:34, Oct 27, 2007: Yeah! Seven!
Seven, 16:41, Oct 18, 2007: Prout !
MooZ, 09:47, Mars 05, 2007: Feed the wiki comme dirait l'autre!
hixcod, 19:26, Mars 04, 2007: et moi donc
Documentation > Graphique > 2D
pages pointant cette page imprimer pdf
similairecommentaire1 fichier joint

Bump Mapping 2D


Cet effet graphique très à la mode dans les démos il y a quelques années est assez facile à coder. La partie la plus complexe est d'essayer de comprendre ce qui se passe derrière l'algorithme pourtant très simple. En passant, les notions présentées dans ce chapitre sont communes à celles du chapitre 4 de la section 3D. En effet, nous allons traiter de lumière et de modèles d’illumination, ainsi que des normales de surfaces. On assume ici que le lecteur connaît ces bases théoriques.


Comme expliqué dans ce tuteur, pour effectuer de l'ombrage, on a besoin du produit scalaire entre la normale de surface et le vecteur de lumière normalisé, et multiplier on doit multiplier le tout par la lumière diffuse. En modifiant la normale de surface sur un point donné, nous changeons aussi l'ombrage de ce point. Le bump mapping se base sur ce principe, excepté que nous ne voulons pas connaître les normales de chaques pixels, mais plutôt leurs signes (pseudo-normales).


Notre effet doit avoir lieu sur un tableau 2D contenant des valeurs représentant la "hauteur" des points, exactement comme on ferait pour du voxel spacing. Cette "bumpmap", ou "carte de bosses" pourrait ressembler à ceci:
img/wiki_up//svel7el9.jpg

Maintenant, pour obtenir le vecteur qui va venir modifier notre normale de surface, nous normalisons avec ces nos pseudo-normales Xd et Yd. La normale Z est celle qui représente directement la "hauteur" du pixel:

Comme vous voyez, les pixels en tons de gris représente la "hauteur" des pixels, blanc étant le plus haut et noir étant le plus bas. Il faut à présent calculer leurs "pente", afin de savoir s'il montent ou s'ils descendent. Pour se faire, il s'agit de vérifier leurs voisins, et de déterminer le signe. Voici le coeur du bump mapping:

Xd = bumpmap[U+1][V] - bumpmap[U-1][V]
Yd = bumpmap[U][V+1] - bumpmap[U][V-1]


Vue de côté, cette même échantillon pourrait avoir l'air de cela:
img/wiki_up//svel7elb.jpg

Nx = Xd
Ny = Yd
Nz = max( 1 - sqrt(Ny ^ 2 + Nx ^ 2 ) , 0 )

longueur = sqrt( Nx ^ 2 + Ny ^ 2 + Nz ^ 2)

Nx /= longueur

Ny /= longueur

Nz /= longueur


En procédant de la sorte, nous modifions la géométrie de la surface, en simulant des variations en hauteur des points sur la surface en modifiant l'ombrage. Bien que les calculs pour se faire ne sont pas trop demandant, il faut quand même procéder de la bonne façon. Également, on assume que la bumpmap est de la même taille que l'écran (dans notre cas, 320x200), et que le vecteur de lumière est directement en face de l'écran à (0,0,-1).


La première chose que l'on peut faire est de précalculer la normale nZ, le 1 - sqrt(Ny ^ 2 + Nx ^ 2 ). La façon la plus commune est d'utiliser un tableau d'une taille très pratique, 256x256, ce qui veut dire que l'on peut précalculer des valeurs pour des valeurs allant entre-128 à 127:

float z[256][256];
float tx,ty;

for (int x=-128;x<128;x++)
{
    for (int y=-128;y<128;y++)
    {
        tx=x/128;
        ty=y/128;

        z[x+128][y+128] = max( 1 - sqrt(tx*tx + ty*ty) , 0);
    }
}


Ce tableau précalculer est en fait ce qu'on appelle une Environment map. On l'utilise souvent pour simuler la réflexion de l’environnement sur une surface (ie : un mirroir) ou pour faire du "faux" phong shading. En effet, du vrai phong shading demande beaucoup de calculs et est difficilement adaptable pour les graphiques en temps réel.

Comme on connaît la normale de surface pour un point donné dans l'environment map, il n'est pas difficile de précalculer le produit scalaire de cette normale, et d'en calculer, a partir d'une source de lumière, la couleur résultante.

void EnvMap()
{
    float nX,nY,nZ;

    for (int y=0;y<256;y++)
    {
        for (int x=0;x<256;x++)
        {
            nX=(x-128)/128.0;
            nY=(y-128)/128.0;
            nZ=1-sqrt(nX*nX+nY*nY);

            if (nZ<0) nZ=0;

            // Phong = ambient + dif*dot + dot^2 * spec
            envmap[x+y*256]=AMBIENT+(byte)min(255,(nZ*DIFFUSE+nZ*nZ *SPECULAR));

            // Lambert = ambient + diffuse * angle
            // envmap[x+y*256] = AMBIENT + DIFFUSE * nZ;
        }
    }
}


Ici je présente deux modèles d'illumination possible: le Lambert Shading et le Phong Shading (mais via du Environment mapping).Nous devons prendre en considération la position de la source de lumière dans nos calculs, et ajuster ses cordonnées pour s’assurer quelle soit considérée comme l'origine (ie: x et y += 128). Voici la fonction principale:

void Bump(int lx,int ly)
{
    int nx,ny; // les pseudo-normales

    // Ajuster la source lumineuse pour qu'elles soient à l'origine
    lx+=128;
    ly+=128;
    int offset=0;

    for (int y=0;y<200;y++)
    {
        for (int x=0;x<320;x++)
        {
            // Obtenir la "pente" de la bumpmap
            nx=bumpmap[offs+1]-bumpmap[offs-1];
            ny=bumpmap[offs+320]-bumpmap[offs-320];

            // Ajustement de la normale d'après la source lumineuse
            nx-=(x-lx);
            ny-=(y-ly);

            // On s'assure qu'on ne dépasse pas l'envmap
            if (nx>255 || nx<0) nx=255;
            if (ny>255 || ny<0) ny=255;

            // Ramene la couleur de l'envmap dans le buffer
            buffer[offset++]=envmap[nx+ny*256];
        }
    }
}


Il ne reste plus qu'a mettre sur pied une palette correspondante. L'effet est très intéressant, et offre beaucoup de possibilité (on utilise le même principe pour simuler l'eau). Je présenterai également bientôt l'effet de simulation de surface aqueuse, avec ombrages et réflexions. Cet effet se réalise également en 3D.


Downloader le fichier ZIP original avec l'exemple.

Auteur de l'article : Shaun



pour optimiser la vitesse, n'oubliez pas que si l'image est immobile, les pentes sont constantes, on peut donc remplacer:
  nx=bumpmap[offs+1]-bumpmap[offs-1]; 
  ny=bumpmap[offs+320]-bumpmap[offs-320];

par :
  nx=bumpmap_pente_x[offs];
  ny=bumpmap_pente_y[offs];

avec bumpmap_pente_x et bumpmap_pente_y calculés comme precedement

De plus, vous pouvez determiner avant le rendu les bords de l'effets. Je m'explique: au lieu de passer sur toute l'image et tester avec deux if si on sort pas de l'envmap, autant ne calculer le bump que dans une zone ou on est sur de ne pas depasser. On peut aussi faire boucler l'envmap avec un nx&=255, ce qui donnera un effet de repetition à la lumiere.

Créé par: jupi` dernière modification: Lundi 26 of Février, 2007 [20:24:55 UTC] par MooZ


Liste des fichiers joints
  nom desc téléchargé taille >
1 : 1 icon fxbump.zip Exemple Déc 17, 2003 [21:46] par jupi` 46.70 Kb 1814
Utilisateurs connectés
Il y a 6 utilisateurs connectés
Hack a Day
    Clubic news
      Utilise Tikiwiki Utilise PHP Utilise Smarty Utilise ADOdb Utilise CSS Utilise RDF
      RSS Wiki RSS Blogues rss Articles RSS Galeries d'images RSS Galeries de fichiers RSS Forums
      [ Temps d'exécution: 0.71 secs ]   [ Mémoire utilisée: 31.28MB ]   [ GZIP Enabled ]   [ Charge du serveur: 0.52 ]