TP2 : Textures
Placage de texture
Étapes pour créer la texture :
- obtention d'un identifiant de texture (glGenTextures)
- lien avec cette texture (glBindTexture)
- spécification des paramètres (glTexParameter*)
- chargement de l'image
- envoie des dimensions et des texels (glTexImage2D)
Toutes ces étapes sont encapsulées par les méthodes load et create de la classe GQTexture pour plus de facilité.
À l'affichage, il faut spécifier sur qu'elle unité de texture ont veut accrocher la texture (glActiveTexture) en la liant avec l'identifiant de texture correspondant (glBindTexture). Dans les shaders, il est alors possible de manipuler les unités de textures auxquelles on a associé un nom lors du passage d'un uniforme (uniform sampler2D Tex2D prend la valeur 0 pour accéder à l'unité 0, par exemple). Regarder la méthode bindNameTexture de la classe GQRefShader qui réalise toutes ces opérations pour vous.
Bien sûr, il faut également fournir les coordonnées de texture de l'objet comme attributs pour pouvoir accéder au sampler par la fonction GLSL texture.
Sphère texturée : globe terrestre
Pour ce TP nous utiliserons le modèle de la sphère pour lequel nous pouvons simplement calculer des coordonnées de texture.
Jour et nuit
Pour simuler l'éclairage par le soleil, il faut ajouter la contribution de la source lumineuse. Comme dans le TP1, calculer un coefficient diffus qui fera varier la couleur finale entre celle de la texture et le noir.
Vous pouvez modifier les positions de la source lumineuse et faire tourner la sphère pour créer une animation.
Charger la deuxième texture "earth2.png" correspondant à la terre vue de nuit sur une deuxième unité de texture. Modifier le code de votre fragment shader pour remplacer le noir par cette texture (vous pouvez utiliser la fonction GLSL mix).
Normal / Bump mapping
Nous allons ajouter du relief à ce globe par la technique de Normal et/ou de Bump mapping.
Normal Mapping
Le principe de cette approche est d'utiliser une texture comme carte des normales de l'objet. Commencez donc par charger la texture "earth3.png" dans la troisième unité de texture. Vous pouvez dans un premier temps visualiser directement cette texture à la surface de la sphère.
Les normales fournies par la texture sont exprimées dans un repère local, tangent à la surface de l'objet. Pour les utiliser, il est donc nécessaire d'exprimer les vecteurs de lumière et de vue dans ce repère. Ajouter donc au vertex shader l'attribut vec3 VertexTangent pour avoir accès à la tangente en chaque sommet et construisez ce repère selon les étapes suivantes :
- transformez et normalisez les vecteurs tangent et normal du repère Model au repère View pour obtenir les vecteurs tv et nv respectivement,
- calculer le vecteur binormale bv par produit vectoriel (fonction cross) des vecteurs tv et nv (attention le produit vectoriel n'est pas commutatif),
- créez la matrice de transformation 3x3 tbnvMatrix dont chaque ligne est constituée des 3 composantes des vecteurs tv, bv et nv :
- si v1 = vec2(a,b) et v2 = vec2(c,d) alors m = mat2(v1, v2) représente la matrice 2x2 dont la première ligne sera (a,c) et la deuxième sera (b,d)
- la fonction GLSL transpose pourra vous être utile
- les vecteurs lt et vt sont obtenus en multipliant la matrice tbnvMatrix par lv et vv respectivement.
Les normales perturbées dans le repère tangentiel sont stockées dans le sampleur textureNormals. Il faut au préalable transformer leurs valeurs d'un intervalle [0;1]³ vers [-1; 1]³.
Utilisez ces normales ainsi que lt et vt dans le fragment shader pour calculer les coefficients diffus et spéculaires.
Bump Mapping
C'est exactement la même marche à suivre que pour le Normal mapping, si ce n'est que la texture d'entrée "earth4.png" est un champ de hauteur duquel il faut déduire la perturbation des normales par comparaison de l'intensité des texels voisins (les fonctions GLSL dFdx et dFdy peuvent être utiles).
Motifs procéduraux
Charger le shader xyz_color qui affiche, sous forme de couleurs, la position des sommets du maillage dans le repère du modèle. Depuis ces shaders, écrire votre propre programme pour obtenir une grille procédurale à la surface de l'objet.
L'idée est d'associer une couleur (ici, blanche ou noire) à chaque point de la surface de l'objet. Pour une grille, il suffit de répéter la procédure pour créer des hachures selon les deux directions et de mélanger le résultat. Pour générer des hachures, il faut donc définir une fonction F qui à la position t associe une couleur c. Cette fonction à la forme :
Dans un premier temps, elle peut être obtenue en utilisant la fonction step(x,t) qui renvoie 0 si t est inférieur à x ou 1 si t est supérieur à x. De cette façon, on obtient une seule marche. Pour obtenir plus de bandes, il faut moduler la fréquence en utilisant la fonction fract et une constante.
Les lignes obtenues sont cependant très crénelées. Pour en obtenir des plus douces, vous pouvez utiliser un cosinus au lieu de fract et la fonction mix pour mélanger les couleurs.