Les triangles 2D
Introduction
Voir mon tutoriel sur le traçage de rectangle flat, gouraud et texturés, je commence en supposant que c’est lu, na =)
Bon, avec ces fichus tuts, vous en savez déjà un peu plus, on va donc aller voir un peu plus loin, mais pas tellement.
En réalité, il arrive rarement que l’on se contente d’afficher un triangle avec une texture, ou bien uniquement un ombrage gouraud. En général on aime fusionner les deux de manière à pouvoir modifier la luminosité de la texture en fonction des lumières et autres contrariétés habituelles.
Il faut donc juste être capable de mixer les deux algos, et de fonctionner en 32bits. Au lieu d’interpoler une valeur de couleur, on en interpolle trois (un rouge, un vert et un bleu), on interpole aussi les coordonées de texture, et si on fait du Z-Buffer, on interpole la valeur Z. On peut même interpoller une valeur Alpha pour la transparence.
Pour mixer le tout, voici comment je fais moi :
- Je trouve la couleur R,G,B qui provient du gouraud
- Je trouve la couleur R,G,B qui provient de la texture
- Je mixe les deux couleurs avec une simple moyenne géométrique, c’est à dire en faisant (en gros) le produit de chaque composante. Rtotal=Rgouraud*Rtexture etc...
- Si l’algo doit faire de la transparence, je vais rechercher la couleur qui se trouve déjà à l’écran au même endroit et j’utilise la formule d’alpha classique : couleur=couleur_originale*alpha+nouvelle_couleur*(1-alpha)
- Et j’affiche le résultat, sous réserve que le pixel soit plus proche si je fais du Z-Buffer.
Pour faire plus complet encore on peut utiliser comme valeur alpha un mix entre la valeur alpha calculée par gouraud, une valeur alpha propre à la texture (alors la texture est en 32bit rgba) et une valeur alpha disponible à l’écran dans les 8 derniers bits. Il faut alors modifier en plus cette valeur alpha à l’écran.
Mais bon...
La correction de perspective
Le système de traçage de triangle « classique » comme proposé dans les tuts en annexe par sur un postulat faux (c’est pas de bol) : la coordonée de la texture au centre du triangle n’est pas la moyenne des coordonées au sommet. Il en va de même pour le gouraud et pour la valeur Z, en fait tout est faux, du début à la fin. (Pas beaucoup, mais quand même...)
Pour comprendre pourquoi, prenons une texture « chemin de fer » :
Si nous nous mettons sur les rails et que nous regardons dans la direction de la voie, nous avons à gauche la vue correcte, et à droite ce que nous donnera notre programme incorrect :
C’est logique, notre algo subdivise la hauteur en sous-hauteurs égales, sans comprendre que plus on est haut, plus on est loin, et que les distances doivent diminuer.
Et encore, comme c’est là ça ne saute pas toujours aux yeux, mais quand ça bouge, je vous jure qu’on ne s’y laisse pas tromper plus d’un dixième de seconde...
Heureusement, ya un jour un mec qui a sortit une feuille et un bic et qui a trouvé (c’était pas dur, remarquez, fallait juste y penser) que si u,v ou n’importe quoi ne pouvait pas s’interpoller linéairement comme ça sur l’écran, n’importe quelle valeur divisée initialement par z pouvait, elle, s’interpoler de cette manière, à condition qu’avant de l’utiliser, on remultiplie la valeur par le bon Z local.
Et comment on le trouve le bon Z local ? Ben c’est jusque 1/Z lui assi, forcément, il s’interpole correctement linéairement.
Alors quoi qu’on fait ? C’est simple :
1. On commence par diviser les valeurs par leur Z respectif. inverse_u1=u1/z1, inverse_v1=v1/z1, inverse_r1=r1/z1 etc... et finalement inverse_z1=1/z1 ;
2. On interpole ces valeurs comme précédement, ca c’est facile
3. Une fois qu’on a besoin de ces valeurs pour dessiner quelque chose d’interessant à l’écran, on remultiplie tout par z, ce qui revient, remarquez, à diviser par 1/z, et ça tombe bien, on l’a justement sous la main : vrai_u= inverse_u/ inverse_z
4. C’est prêt, régalez-vous...
Evidement, avec des calculs pareils, il faut passer par virgule flottante et ça trace pas beaucoup. Petit exercice : trouver comment faire ça rapidement =)