Mandragor


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 :

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 =)