Multi-textures - Université de Strasbourg
Transcription
Multi-textures - Université de Strasbourg
Université de Strasbourg Logiciels et Matériels Graphique Master 1 ISI Feuille de TP Multi-textures 1 Multi-textures : le principe Bien souvent un rendu nécessite de recourir à plusieurs textures pour sotcker les données utiles au rendu (couleurs, géométrie, éclairage, ...). Dans ce cas, il est nécessaire d’accéder à plusieurs textures depuis un shader. Il faut donc que le shader soit lié à plusieurs textures différentes. On parle dans ce cas de multitexturing. 1.1 Multitexturing et GLSL En GLSL, l’accès aux textures se fait via un sampler défini en tant que variable uniforme. Pour qu’un shader prenne en compte plusieurs textures, il suffit de définir plusieurs samplers dans un même shader ou dans les différents shaders d’un programme de shaders. La difficulté majeure se situe au niveau d’OpenGL pour activer et lier aux différents samplers les textures à utiliser. 1.2 Activation de plusieurs textures Dans le TP sur les textures, nous avons vu qu’au moment du dessin, il faut activer une texture via la fonction glBindTexture. Mais cette façon de procéder ne permet d’activer qu’une seule texture à la fois. Pour contourner ce problème, OpenGL offre un mécansime appelé unités de textures. Chaque unité de textures permet d’activer une texture à la fois. En utilisant plusieurs unités de textures1 pour même shader, il est ainsi possible d’activer plusieurs textures à la fois. Pour utiliser une unité de textures, il faut appeler la fonction : void glActiveTexture(GLenum texture) où texture spécifie l’unité de textures utilisée et doit être une constante du type GL_TEXTUREi où i varie en 0 et la plus grande valeur entre GL_MAX_TEXTURE_COORDS−1 et GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS−12 . Remarque Les spécifications d’OpenGL assurent que GL_T EXT U REi = GL_T EXT U RE0 + i 1.2.1 Exemple //Activation de la premiere texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texId1); 1 Le nombre d’unités de textures disponibles dépend du matériel graphique installé sur la machine. deux valeurs peuvent être récupérées via la fonction glGetIntegerv. 2 Ces 1 //Activation de la deuxieme texture glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texId2); //Activation d’un programme de shader utilisant ces deux textures glUseProgram(pgmId); //Le dessin //On oublie pas de desactiver les elements utilises glUseProgram(0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); 1.3 Liaisons entre unité de textures et sampler GLSL Pour pouvoir utiliser ces différentes textures dans un shader, il faut lier les différentes unités de textures utilisées aux différents samplers des shaders. Un sampler peut être vu comme un entier représentant le numéro de l’unité de texture à accéder lors d’un accès texture. Pour lier une unité de textures à un sampler, il suffit de modifier la valeur de ce sampler en lui attribuant le numéro de l’unité de texture souhaitée. Comme un sampler est une variable uniforme, cela se fait simplement en modifiant cette variable uniforme via les fonctions glGetUniformLocation et glUniform*. 1.3.1 Exemple On suppose que le programme de shaders shaderPgmId définit et utilise deux variables de type sampler2D appelées, respectivement, tex1 et tex2. //On memorise l’emplacement des samplers dans le shader. GLint tex1Loc = glGetUniformLocation(shaderPgmId, "tex1"); GLint tex2Loc = glGetUniformLocation(shaderPgmId, "tex2"); //... //Association des unites de textures aux differents samplers glUseProgram(shaderPgmId); //On associe l’unite de texture GL_TEXTURE0 au sampler tex1 glUniform1i(tex1Loc, 0); //On associe l’unite de texture GL_TEXTURE1 au sampler tex2 glUniform1i(tex2Loc, 1); glUseProgram(0); //On peut maintenant utiliser le shader avec les deux textures Exercice 1 : Multitexturing Dessiner un cube. Utiliser un shader pour plaquer sur chacune de ses faces les deux textures couleurs fournies avec le sujet (woodBox et tex2). Vous pouvez combiner les couleurs des texels des deux textures en utilisant la fonction mix, pré-définie en GLSL. Il faut cependant que la texture de fond soit la texture woodBox. 2 2 Bump-mapping L’éclairage de Phong se base, en partie, sur les normales des sommets pour calculer la couleur de l’objet éclairé. Jusqu’à présent, les normales sont spécifiées pour chaque sommet de l’objet géométrique et sont interpolées par la carte graphique pour chaque fragment. La technique du bump mapping utilise une texture pour stocker les normales utilisées pour calculer l’éclairage de l’objet. Les normales ne sont plus simplement interpolées linéairement entre les sommets d’un triangle mais peuvent varier plus finement sur la surface de ce triangle. Pour être tout à fait complet, le rendu d’un objet utilisant le bump mapping doit également afficher une information de couleur généralement fournie par une texture couleur. Exercice 2 Rendre un quadrilatère en utilisant un algorithme de bump mapping. Les normales proviendront de la carte de normales fournie avec le sujet (rockwall_normal.bmp). Vous devez également utiliser la texture couleur rockwall.bmp. Attention, les normales étant stockées dans une image, il a fallu les transformer pour passer de [−1; −1] → [0; 1]. Elles ont donc subit la transformation suivante : 1 → 1 → n + f (− n) = ∗− 2 2 Il faudra donc leur faire subir la transformation inverse au moment de leur utilisation dans le fragment shader. 3