Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D...

58
Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders Modélisation 3D et Synthèse Fabrice Aubert fabrice.aubert@lifl.fr IEEA - Master Info - Parcours IVI 2012-2013 F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 1 / 58

Transcript of Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D...

Page 1: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Chapitre 5 : Rendu projectif en OpenGLVertex et Fragment shaders

Modélisation 3D et Synthèse

Fabrice [email protected]

IEEA - Master Info - Parcours IVI

2012-2013

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 1 / 58

Page 2: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Contenu du chapitre

I Introduction aux techniques dites modernes des librairies de prog3D (OpenGL/Direct3D) :buffer objects, shaders.

I On introduit également, dans le contexte OpenGL, des concepts fondamentaux pour lavisualisation 3D : l’éclairement et les textures.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 2 / 58

Page 3: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

1 Tracé des polygones

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 3 / 58

Page 4: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Mode immédiat

I Deprecated depuis 3.0 (compatibility profile)

glBegin (GL_TRIANGLE_STRIP ) ;/ / a t t r i b u t s sommet V0g l C o lo r 3 f ( 1 , 0 , 0 ) ;g lVe r tex3 f (−1 ,−1 ,0);/ / a t t r i b u t s sommet V1g l C o lo r 3 f ( 0 , 1 , 0 ) ;g lVe r tex3 f (−1 ,1 ,0) ;/ / a t t r i b u t s sommet V2g l C o lo r 3 f ( 0 , 0 , 1 ) ;g lVe r tex3 f (1 ,−1 ,0) ;/ / a t t r i b u t s sommet V3g l C o lo r 3 f ( 1 , 1 , 0 ) ;g lVe r tex3 f ( 1 , 1 , 0 ) ;

glEnd ( ) ;

Rappel : ordre parTRIANGLE_STRIP :

glBegin (GL_TRIANGLE_STRIP ) ;g lVer tex . . . ( V0 ) ;g lVer tex . . . ( V1 ) ;g lVer tex . . . ( V2 ) ;g lVer tex . . . ( V3 ) ;g lVer tex . . . ( V4 ) ;. . .

glEnd ( ) ;

I Tracé moderne : donner les sommets par buffer.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 4 / 58

Page 5: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Array Buffer

I Affecter une zone mémoire d’OpenGL (server side memory = carte graphique si possible)avec des données => buffer objects.

I Plusieurs type de buffers : pour les attributs de sommets on utilise les array buffers(tableaux). Technique appelée anciennement Vertex Buffer Objects.

I On copie les données de l’application (client side memory) dans la mémoire OpenGL.

unsigned i n t bu f fe rVe r tex ;

void Square : : i n i t B u f f e r ( ) {

/ / ve r tex [ ] = { x0 , y0 , z0 , x1 , y1 , z1 , x2 , y2 , z2 , e tc }f l o a t ver tex []={−1 ,−1 ,0 ,−1 ,1 ,0 ,1 ,−1 ,0 ,1 ,1 ,0};

/ / géné r e r un " po in teu r " ( ou i d e n t i f i a n t ) dans une zone mémoire OpenGLglGenBuffers (1 ,& bu f fe rVe r tex ) ;

/ / l e tab leau de donnée a c t i f correspond à l ’ i d e n t i f i a n t bu f f e rVe r tex/ / ( un seul ar ray b u f f e r a c t i f à l a f o i s )g lB indBu f fe r (GL_ARRAY_BUFFER, bu f fe rVe r tex ) ;

/ / a f f e c t a t i o n des données server avec les donnée c l i e n t s/ / ( i c i 12 f l o a t dont cop iés depuis l e tab leau ver tex ) .g lBu f fe rDa ta (GL_ARRAY_BUFFER,12∗ s i z e o f ( GLf loa t ) , ver tex ,GL_STATIC_DRAW ) ;

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 5 / 58

Page 6: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Tracer les données des array buffers (OpenGL 2.1)

I OpenGL 2.1 ? Pourquoi ?

void Square : : drawBuffer ( ) {/ / a c t i v e r l ’ a l imen ta t i on de l ’ a t t r i b u t g l_Ver tex pour chaque sommet t r a c ég lEnab leC l i en tS ta te (GL_VERTEX_ARRAY ) ;

/ / l e b u f f e r courant des données :g lB indBu f fe r (GL_ARRAY_BUFFER, bu f f e rVe r tex ) ;

/ / l es a t t r i b u t s g l_Ver tex seront lus depuis l e b u f f e r bu f f e rVe r tex ( i . e . l e b u f f e r courant ) :g lVe r texPo in te r (3 ,GL_FLOAT, 0 , 0 ) ;

/ / commande de t r a c é ( exé cu t i on du p i p e l i n e de t r a c é ) avec 4 sommets :glDrawArrays (GL_TRIANGLE_STRIP , 0 , 4 ) ;

g l D i s a b l e C l i e n t S t a t e (GL_VERTEX_ARRAY ) ;

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 6 / 58

Page 7: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Gestion mémoire

I Toujours se rappeler qu’OpenGL "travaille" avec les valeurs courants des états(glBindBuffer(...) indique par exemple le buffer courant actif).

I Ne pas oublier de gérer correctement la mémoire si besoin (cf tous les glDelete(...),par exemple glDeleteBuffers).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 7 / 58

Page 8: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Pipeline de tracé

⇒ tout sommet provoque l’exécution d’un programme appelé Vertex Shader.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 8 / 58

Page 9: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Vertex Shader

I Chaque sommet subit le vertex shader.

I = programme exécuté (par la carte graphique si possible).

I = programme écrit dans un langage particulier : GLSL (OpenGL Shading Language).

I OpenGL permet de compiler/linker et activer des programmes GLSL

# vers ion 110

void main ( ) {g l _ P o s i t i o n = g l _ P r o j e c t i o n M a t r i x∗gl_ModelViewMatr ix∗g l_Ver tex ;

}

I ⇒ langage inspiré de C/C++

I Tous les états sont accessibles par des "variables" identifiées par gl_.

• gl_Vertex : de type vec4 correspond aux coordonnées (x ,y ,z,w) (fourni par lesdonnées lues dans le ARRAY_BUFFER).

• gl_ModelViewMatrix : de type mat4 correspond à la valeur de la MODELVIEW.• gl_Projection : de type mat4 correspond à la valeur de la matrice PROJECTION.

I Le vertex shader doit fournir obligatoirement gl_Position à la suite du pipeline.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 9 / 58

Page 10: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

GLSL

I Tout le langage GLSL est résumé sur les 4 dernières pages dehttp://www.khronos.org/files/opengl-quick-reference-card.pdf

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 10 / 58

Page 11: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Rasterization

⇒ tout pixel qui est tracé provoque l’exécution d’un programme appelé Fragment Shader.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 11 / 58

Page 12: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Fragment shader

I Même langage que vertex shader : GLSL

I Doit fournir une couleur pour le pixel qui est en train d’être tracé (affecter gl_FragColorde type vec4).

Exemple de base (listing du fichier essai.frag) :

# vers ion 110

void main ( ) {/ / a f f e c t a t i o n avec du v e r t ( i . e . vec4 i n t e r p r é t é comme ( rouge , ver t , bleu , alpha ) ) .gl_FragColor=vec4 ( 0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 ) ;

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 12 / 58

Page 13: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Compilation et activation d’un shader

I Compilation/link par l’application OpenGL :

void create ( ) {programId=glCreateProgram ( ) ;

ve r t ex Id =glCreateShader (GL_VERTEX_SHADER) ;f ragment Id=glCreateShader (GL_FRAGMENT_SHADER) ;

glAt tachShader ( programId , ve r t ex Id ) ;g lAt tachShader ( programId , f ragment Id ) ;

char ∗source= readF i l e ( " essai . v e r t " ) ;glShaderSource ( ver tex Id ,1 ,& source ,NULL ) ;char ∗source= readF i l e ( " essai . f r ag " ) ;glShaderSource ( fragmentId ,1 ,& source ,NULL ) ;

glCompileShader ( ve r t ex Id ) ;glCompileShader ( f ragment Id ) ;

glLinkProgram ( programId ) ;}

I Utilisation (activation pour tous les tracés effectués par draw() par exemple) :

void drawScene ( ) {. . .glUseProgram ( programId ) ;draw ( ) ;. . .

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 13 / 58

Page 14: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Resultat

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 14 / 58

Page 15: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Interpolation de variables : varying

I Le vertex shader peut calculer des valeurs qui seront fournies à la suite du pipeline(variables en sortie).

I Le fragment shader peut récupérer ces variables dont les valeurs ont subi une interpolationbilinéaire par rapport aux valeurs de chacun des sommets (variables en entrée).

I Ces variables, qui apparaissent avec le même nom dans le vertex et le fragment, sontqualifiées de varying.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 15 / 58

Page 16: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Exemple : interpolation des couleurs

Vertex Shader :

# vers ion 110

vary ing vec4 couleur ;

void main ( ) {cou leur=g l_Co lor ; / / g l_Co lor es t a l iment é par l e b u f f e r d ’ a t t r i b u t GL_COLOR_ARRAYg l _ P o s i t i o n = g l _ P r o j e c t i o n M a t r i x∗gl_ModelViewMatr ix∗g l_Ver tex ;

}

Fragment Shader :

# vers ion 110

vary ing vec4 couleur ;

void main ( ) {g l_FragColor=cou leur ;

}

Tracé OpenGL :

g lEnab leC l i en tS ta te (GL_VERTEX_ARRAY ) ;g lB indBu f fe r (GL_ARRAY_BUFFER, bu f fe rVe r tex ) ;g lVe r texPo in te r (3 ,GL_FLOAT, 0 , 0 ) ;

g lEnab leC l i en tS ta te (GL_COLOR_ARRAY) ;g lB indBu f fe r (GL_ARRAY_BUFFER, bu f f e rCo lo r ) ;g lCo lo rPo in te r (3 ,GL_FLOAT, 0 , 0 ) ;

glDrawArrays (GL_TRIANGLE, 0 , 3 ) ;

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 16 / 58

Page 17: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Tracé de faces avec indices

f l o a t cube[]={−1,−1,−1, / / Vertex 0−1,1,−1, / / Vertex 11,−1,−1, / / Vertex 21 ,1 ,−1 , / / Vertex 3−1,−1,1, / / Vertex 4−1 ,1 ,1 , / / Vertex 51 ,−1 ,1 , / / Vertex 61 ,1 ,1 , / / Vertex 7} ;

unsigned i n t i n d i c e [ ]= {0 ,1 ,2 ,3 ,6 ,7 ,4 ,5 ,0 ,1 ,5 ,7 ,1 ,3 , / / " couverc le dessus "6 ,4 ,2 ,0 } ; / / " couverc le dessous "

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 17 / 58

Page 18: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Exemple du cube : initialisation buffers

GLuint vertexCube , indiceCube ;void i n i tBu f f e rCube ( ) {

f l o a t cube[]={−1 ,−1 ,−1 ,−1 ,1 ,−1 ,1 ,−1 ,−1 ,1 ,1 ,−1 ,−1 ,−1 ,1 ,−1 ,1 ,1 ,1 ,−1 ,1 ,1 ,1 ,1};

unsigned i n t i n d i c e [ ]= {0 ,1 ,2 ,3 ,6 ,7 ,4 ,5 ,0 ,1 ,5 ,7 ,1 ,3 ,6 ,4 ,2 ,0 } ;

g lGenBuffers (1 ,& vertexCube ) ;g lB indBu f fe r (GL_ARRAY_BUFFER, vertexCube ) ;g lBu f fe rDa ta (GL_ARRAY_BUFFER,24∗ s i z e o f ( GLf loa t ) , cube ,GL_STATIC_DRAW ) ;

glGenBuffers (1 ,& indiceCube ) ;g lB indBu f fe r (GL_ELEMENT_ARRAY_BUFFER, indiceCube ) ;g lBu f fe rDa ta (GL_ELEMENT_ARRAY_BUFFER,18∗ s i z e o f ( GLuint ) , i nd ice ,GL_STATIC_DRAW ) ;

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 18 / 58

Page 19: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Exemple du cube : tracé

g lEnab leC l i en tS ta te (GL_VERTEX_ARRAY ) ;g lB indBu f fe r (GL_ARRAY_BUFFER, vertexCube ) ;g lVe r texPo in te r (3 ,GL_FLOAT, 0 , 0 ) ;

g lB indBu f fe r (GL_ELEMENT_ARRAY_BUFFER, indiceCube ) ;

/ / s t y l e de p r i m i t i v e s , nombre de sommets , type des ind ices , début de l e c t u r e dans les ind i ces ( en u n i t machine )glDrawElements (GL_TRIANGLE_STRIP,10 ,GL_UNSIGNED_INT , ( void ∗)( s i z e o f ( GLuint )∗0 ) ) ;glDrawElements (GL_TRIANGLE_STRIP,4 ,GL_UNSIGNED_INT , ( void ∗)( s i z e o f ( GLuint )∗10) ) ;glDrawElements (GL_TRIANGLE_STRIP,4 ,GL_UNSIGNED_INT , ( void ∗)( s i z e o f ( GLuint )∗14) ) ;

g l D i s a b l e C l i e n t S t a t e (GL_VERTEX_ARRAY ) ;

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 19 / 58

Page 20: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

GL TRIANGLES

Pour le cube, le GL_TRIANGLE_STRIP n’est pas nécessairement bien adapté.

I On peut également spécifier tous les triangles dans le tableau d’indices.

I Puis tracer avec un seulglDrawElements(GL_TRIANGLES,??,GL_UNSIGNED_INT,(void *)0).

Exercice : combien de triangles à tracer ? quel est alors le tableau d’indices (indiquez le débutpour les 3 premiers triangles) ?

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 20 / 58

Page 21: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

2 Eclairement

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 21 / 58

Page 22: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Réalisme

I Pour ajouter du réalisme aux scènes 3D, OpenGL propose de calculer des couleurs poursimuler un éclairement de la scène par des sources lumineuses.

⇒ calcul de la couleur provenant de 2 contributions : réflexion diffuse (couleur mat) et réflexionspéculaire (couleur brillante : tâche spéculaire).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 22 / 58

Page 23: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Données

Les données nécessaires au calcul d’éclairement sont :

I Les sources (position, caractéristiques d’éclairement).

I Le matériel des objets (caractéristiques qui traduisent comment est réfléchie la lumière dessources).

I On peut avoir jusqu’à 8 sources simultanées en OpenGL. Elles sont identifiées par lesconstantes GL_LIGHT0, GL_LIGHT1, ..., GL_LIGHT7.

I L’instruction qui permet de donner les caractéristiques des sources : glLight.

I Il existe deux seuls matériels (un pour les faces FRONT et un pour les BACK). Il faut doncchanger les caractéristiques dès qu’on veut tracer un objet avec un matériel différent del’objet précédemment tracé.

I L’instruction qui permet de donner les caractéristiques des matériels : glMaterial.

I Les composantes (rouge, vert, bleu) qui apparaissent dans la suite sont comprises entre 0et 1.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 23 / 58

Page 24: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Modèle d’éclairement

I Dans ce chapitre, pour illustrer l’éclairement on choisit le modèle empirique de Phong.

I Très simple, mais aussi très éloigné de la réalité.

I Le vecteur V est appelé vecteur d’observation, le vecteur L est appelé vecteurd’éclairement.

I La position de la source 0 est donnée parglLightfv(GL_LIGHT0,GL_POSITION,<float *pos>) où pos=(x,y,z,w).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 24 / 58

Page 25: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Réflexion diffuse 1/2

I On suppose qu’un objet (un matériel) diffuse la lumière reçue de manière uniforme danstoutes les directions.

I La lumière (i.e. la couleur) perçue ne dépend donc pas de la position de l’observateur.

I L’intensité diffusée dépend des caractéristiques du matériel (matériel rouge =« beaucoup »de rouge diffusé, matériel noir = aucune intensité diffusée, etc).

I ⇒ Définition d’un coefficient de matériel kd = (rouge,vert,bleu) pour définir cettecaractéristique (toujours ∈ [0,1]).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 25 / 58

Page 26: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Réflexion diffuse 2/2

I L’intensité diffusée dépend de l’angle d’incidence des rayons lumineux sur la surface del’objet

• un éclairement direct (i.e. la lumière arrive orthogonalement à la surface) donne unediffusion maximale.

• un éclairement fuyant (i.e tangent à la surface) donne un éclairement nul.• on souhaite que la diffusion varie « continuement »entre ces 2 positions de la manière

la plus réaliste possible.• ⇒ prise en compte de la normale (i.e. vecteur orthogonal) à la surface au point P.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 26 / 58

Page 27: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Calcul du diffus

I On suppose N et L sont normés (‖N‖= ‖L‖= 1).

I Le calcul de l’intensité du diffus par cos(N,L) = L ·N est un « bon »choix.

I On donnera une couleur de réflexion diffuse Kd pour indiquer la couleur réfléchie par lematériel.

⇒ Couleurdiffus(P) = Kd (N ·L)

I seul le « coté »dirigé par la normale est éclairé (si N ·L < 0 alors éclairement nul).

I ⇒ important de spécifier correctement les normales.

I Composante Kd=(rouge,vert,bleu) couleur souhaitée pour le matériel.

I glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE,<GLfloat Kd[3]>);

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 27 / 58

Page 28: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Calcul aux sommets

I En OpenGL, on se contente souvent de calculer l’éclairement diffus uniquement auxsommets.

I ⇒ obtention d’une couleur en chaque sommet.

I La couleur des pixels lors de la rasterization est alors simplement obtenue par interpolationlinéaire des couleurs.

I Le résultat est satisfaisant par rapport à un calcul sur chacun des points du triangle 3D(bien que ce calcul d’éclairement diffus ne soit pas linéaire sur l’espace écran !⇒approximation convenable).

⇒ l’interpolation linéaire des couleurs, dans le cadre de l’éclairement est appelée interpolationde Gouraud.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 28 / 58

Page 29: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Normales 1/3

I Pour le calcul d’éclairement il faut spécifier les normales.

I Si le calcul s’effectue en chaque sommet, il faut fournir à chaque sommet une normale.

g lEnab leC l i en tS ta te (GL_VERTEX_ARRAY ) ;g lB indBu f fe r (GL_ARRAY_BUFFER, ve r t exBu f f e r ) ;g lVe r texPo in te r (3 ,GL_FLOAT, 0 , 0 ) ;

g lEnab leC l i en tS ta te (GL_NORMAL_ARRAY) ;g lB indBu f fe r (GL_ARRAY_BUFFER, normalBuf fer ) ; / / a t t r i b u é auparavantglNormalPoin ter (GL_FLOAT, 0 , 0 ) ;

glDrawArrays (GL_TRIANGLES , . . . ) ;

I Fournir le vecteur orthogonal au polygone tracé ?⇒ pas nécessairement ! (liberté totale dedonner la normale qu’on souhaite).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 29 / 58

Page 30: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Normales 2/3

I Pouvoir spécifier une normale différente en chaque sommet permet d’obtenir le calculd’éclairement qui correspond au mieux à la forme souhaitée.

I ⇒ permet d’obtenir une perception d’un objet lisse en « jouant »uniquement avec lesnormales !

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 30 / 58

Page 31: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Normales 3/3

I Résultat pour le diffus :

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 31 / 58

Page 32: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Exemple de spécification des normales pour un objetcomplexe

I La normale de l’objet à représenter peut ne pas être connue (surface « réelle »inconnue).

I ⇒ Prendre la moyenne des normales aux facettes incidentes au sommet peut donner unebonne approximation de la surface lisse.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 32 / 58

Page 33: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Effets « spéciaux »avec des normales

I sur l’animation on ne voit pas tous les polygones (grille plus finement subdivisée).

I il s’agit du principe appliqué par la technique dite du « Bump mapping » : spécifier lesnormales d’un relief sans toucher à la géométrie de l’objet. Seul le calcul d’éclairementdonne la perception de relief.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 33 / 58

Page 34: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Eclairement dans les shaders

I Tous les vecteurs apparaissant dans les calculs doivent être exprimés dans le mêmerepère : les calculs d’éclairement se feront dans le repère Eye.

I Transformation des sommets : vertexEye=gl_ModelViewMatrix*gl_Vertex;

I Transformation des normales : nEye=gl_NormalMatrix*gl_Normal;. Attention :gl_NormalMatrix est une matrice 3x3 et gl_Normal est un vec3.

I Pourquoi ? A cause des éventuels scales :

avant transformation après transformation par MODELVIEW

I La matrice correcte pour transformer les normales est (M−1)t où M est la sous-matrice3x3 (3 premières lignes, 3 premières colonnes) de MODELVIEW.

(cf http://www.lighthouse3d.com/opengl/glsl/index.php?normalmatrix).F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 34 / 58

Page 35: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Shader

Vertex shader :

# vers ion 110

vary ing vec4 couleur ;

void main ( ) {f l o a t i n t e n s i t e D i f f u s ;

vec3 N, L ;

N=gl_NormalMatr ix∗gl_Normal ;

/ / Source supposée d i r e c t i o n n e l l e i c i :L=gl_L ightSource [ 0 ] . p o s i t i o n . xyz ; / / dé j à exprimé dans l e repère Eye

L=normal ize ( L ) ;N=normal ize (N ) ;

i n t e n s i t e D i f f u s =max( dot (N, L ) , 0 . 0 ) ;

cou leur= i n t e n s i t e D i f f u s∗g l_ F r o n t M a te r i a l . d i f f u s e ;

g l _ P o s i t i o n = g l _ P r o j e c t i o n M a t r i x∗gl_ModelViewMatr ix∗g l_Ver tex ;}

Fragment shader :

# vers ion 110

vary ing vec4 couleur ;

void main ( ) {g l_FragColor=cou leur ;

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 35 / 58

Page 36: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Remarques sur GLSL

On dispose en GLSL des types propres à la 3D (vec, mat), et d’une manipulation assez soupledes variables :

void main ( ) {vec4 a=vec4 ( 0 . 1 , 0 . 2 , 0 . 3 , 0 . 4 ) ; / / cons t ruc teu rf l o a t b=a . x ; / / accès au champ xvec2 c=a . xy ; / / opé r a t i o n d i t e de s i z z l i n gf l o a t d=a .w;mat2 e = mat2 ( 1 . 0 , 0 . 0 , 1 . 0 , 0 . 0 ) ;f l o a t f =e [ 1 ] [ 1 ] ; / / accès tab leauvec2 g=e [ 1 ] ; / / 2ieme colonne .. . .

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 36 / 58

Page 37: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Spéculaire

I La spécularité traduit l’aspect « brillant »de l’objet.

I La réflexion spéculaire provient de la réflexion (au sens « miroir ») des rayons lumineux surl’objet.

I ⇒ on considère alors la direction miroir R du vecteur d’éclairement L (R est le symétriquede L par rapport à N).

I L’intensité de la réflexion spéculaire est maximale dans la direction R et est atténuée autourde cette direction R.

⇒ L’intensité perçue (i.e. la couleur) par l’observateur va donc dépendre de sa position parrapport à la direction R.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 37 / 58

Page 38: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Calcul spéculaire

I Le calcul de V .R (cosinus de l’angle entre V et R) donne une approximation correcte del’effet spéculaire (maximal dans la direction si R dirigé directement sur l’observateur ;atténué autour).

I Comme pour le diffus : on affecte une caractéristique Ks = (rouge,vert,bleu) pour lematériel.

I Ne pas oublier : tous les vecteurs normés (V .R = cos(V ,R) ∈ [0,1]).

⇒ CouleurSpéculaire(P) = Ks(V ·R)

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 38 / 58

Page 39: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Résultat

I Le calcul du spéculaire donne une « tache »lumineuse sur l’objet (conséquence de laréflexion des rayons lumineux).

I Pour accentuer ou atténuer l’effet, on donne également un coefficient de brillance s pouraccentuer ou atténuer l’effet autour de la direction principale.

I ⇒ CouleurSpéculaire(P) = Ks(V ·R)s

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 39 / 58

Page 40: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Spécifier le spéculaire en OpenGL

Ce sont les même instructions que pour l’ambiant et le diffus :

I glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, <GLfloat Ks[3]>);

I Brillance : glMateriali (GL_FRONT_AND_BACK,GL_SHININESS,<int brillance>);

On peut récupérer ces données dans les shaders avec les built-ingl_FrontMaterial.specular (de type vec4) et gl_FrontMaterial.shininess (de typefloat).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 40 / 58

Page 41: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Spéculaire calculé au sommet

I Spéculaire : très mal rendu s’il est calculé uniquement au sommet.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 41 / 58

Page 42: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Interpolation de Phong

I On calcule l’éclairement spéculaire en chacun des pixels (surcout en temps de calcul).

I Avec quels vecteurs ? on prend les vecteurs L,V ,N interpolés linéairement par rapport auxvaleurs aux sommets (variables L,V ,N définies comme varying).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 42 / 58

Page 43: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

3 Variables uniform

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 43 / 58

Page 44: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Communiquer des valeurs aux shaders

I Communiquer des valeurs spécifiques à chaque sommet⇒ attributs de sommets(glVertexPointer, glColorPointer par exemple)

I Communiquer des valeurs calculées dans le vertex et transmises par interpolation auxfragments⇒ variables qualifiées de varying

I Communiquer des valeurs pour paramétrer les shaders (vertex ou fragment)⇒ variablesqualifiées de uniform

• Une variable uniforme peut changer entre chaque tracé (glDraw...) par l’applicationOpenGL, mais leur valeur reste constante durant l’exécution des vertex/fragmentshaders (lecture seule).

Exemple : modifier les coordonnées des sommets pour effectuer une dilatation.

⇒ déplacer le sommet dans la direction de la normale selon un certain facteur

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 44 / 58

Page 45: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Vertex shader

# vers ion 110

uni form f l o a t f a c t e u r ;

vary ing vec4 c o u l e u r D i f f u s ;vary ing vec3 N, L ,V ;

void main ( ) {f l o a t i n t e n s i t e ;vec4 ver texLoca l ;vec4 vertexEye ;

/ / déplacement du sommetver texLoca l= f a c t e u r∗vec4 ( gl_Normal ,0 )+ g l_Ver tex ;

/ / t r ans fo rma t i on & l i g h t i n gvertexEye=gl_ModelViewMatr ix∗ver texLoca l ;

V=vec3(−gl_ModelViewMatr ix∗g l_Ver tex ) ;L=g l_L ightSource [ 0 ] . p o s i t i o n . xyz−vertexEye . xyz / vertexEye .w;N=gl_NormalMatr ix∗gl_Normal ;

L=normal ize ( L ) ;V=normal ize (V ) ;N=normal ize (N ) ;

i n t e n s i t e =dot (N, L ) ;

c o u l e u r D i f f u s = g l _ F ro n t Ma t e r i a l . d i f f u s e∗i n t e n s i t e ;

g l _ P o s i t i o n = g l _ P r o j e c t i o n M a t r i x∗vertexEye ;}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 45 / 58

Page 46: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Affecter les variables uniform

Dans l’application OpenGL on affecte les variables uniform des shaders avec glUniform :

GLuint programId ;GLuint l oca t i onFac teu r ;

void i n i t ( ) {programId=readMyShader ( " d i l a t a t i o n " ) ; / / f o n c t i o n u t i l i t a i r e pour l i r e / compi ler / l i n k e r

/ / l es shaders des f i c h i e r s d i l a t a t i o n . v e r t e t d i l a t a t i o n . f r ag par exemple

l o ca t i onFac teu r =glGetUni formLocat ion ( programId , " f a c t e u r " ) ; / / r écupé r e r où se t rouve " f a c t e u r " dans l e shader}

void draw ( ) {glUseProgram ( programId ) ;g lUn i fo rm1f ( loca t ionFac teur , 0 . 1 ) ; / / a f f e c t e l a v a r i a b l e f a c t e u r du shader avec l a va leur 0.1

obj . drawBuffer ( ) ; / / commande de t r a c é

glUseProgram ( 0 ) ;}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 46 / 58

Page 47: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

4 Texture

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 47 / 58

Page 48: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Définition (intuitive)

I Une texture est une « image », c’est à dire une grille de pixels.I Les pixels de la texture sont appelés texels (pour les différencier des pixels de l’écran

graphique).I Chaque texel est localisé dans la texture par ses coordonnées s et t .I Toute l’image de la texture est décrite par s ∈ [0,1] et t ∈ [0,1]

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 48 / 58

Page 49: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Plaquer une texture

I Consiste à associer à chaque point 3D des coordonnées de texture pour lui associer untexel de l’image texture

I Plaquage linéaire sur un triangle :• Il suffit d’associer des coordonnées de texture uniquement aux sommets.• Les coordonnées de texture des pixels sont alors interpolées linéairement lors du

remplissage du triangle.

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 49 / 58

Page 50: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Chargement d’une image de texture

I On doit attribuer une zone mémoire OpenGL pour accueillir l’image (mémoire qualifiée detexture buffer).

GLuint t ex_ id ;void i n i t T e x t u r e ( ) {

/ / géné r a t i o n d ’ un i d e n t i f i a n tglGenTextures (1 ,& tex_ id ) ;

/ / l a t e x t u r e courante sera l ’ u n i t é 0 à l a q u e l l e on a f f e c t e l a t e x t u r e tex_ idg lAc t i veTex tu re (GL_TEXTURE0 ) ;g lB indTexture (GL_TEXTURE_2D, tex_ id ) ; / / t ou tes les i n s t r u c t i o n s qu i s u i v r o n t s ’ adresseront à tex_ id

/ / a f f e c t a t i o n de l ’ image de l a t e x t u r eglTexImage2D (

GL_TEXTURE_2D, / / t e x t u r e 2D (= image )0 , / / niveau de mipmap ( sera vu plus ta rd )3 , / / l e tab leau est à i n t e r p r é t e r par " paquet " de

/ / t r o i s va leurs consé cu t i veswidth , height , / / t a i l l e en p i x e l s de l ’ image0 , / / ges t ion des bords pour reco l lement

/ / ( dans ce cours = 0)GL_RGB, / / i n t e r p r é t a t i o n par OpenGL ( image sera

/ / s tockée en va leurs de Rouge , Vert , Bleu )GL_UNSIGNED_BYTE, / / format du tab leau ( i c i unsigned byte )image ) ; / / l ’ image ( tab leau contenant les t e x e l s ) .

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 50 / 58

Page 51: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Attribution des coordonnées de texture

I On peut plaquer plusieurs textures simultanément lors d’un même tracé : gestion desunités de texture.

I Pour chaque unité de texture, on peut spécifier :

• Une texture distincte (i.e. un identifiant distinct)• Des coordonnées de textures indépendantes et distinctes (i.e. plusieurs coordonnées

de texture pour chaque sommet).

GL_TEXTURE0 GL_TEXTURE1 GL_TEXTURE2 placage des 3 unités

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 51 / 58

Page 52: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Attribution des coordonnées de texture

Affectation de la mémoire OpenGL avec des coordonnées de textures :

void i n i t B u f f e r ( ) {f l o a t ver tex []={−1 ,−1 ,0 ,−1 ,1 ,0 ,1 ,−1 ,0 ,1 ,1 ,0};f l o a t t e x t u r e [ ] = { 0 , 0 , 0 , 1 , 1 , 0 , 1 , 1 } ;

g lGenBuffers (1 ,& bu f fe rVe r tex ) ;g lB indBu f fe r (GL_ARRAY_BUFFER, bu f f e rVe r tex ) ;g lBu f fe rDa ta (GL_ARRAY_BUFFER,12∗ s i z e o f ( GLf loa t ) , ver tex ,GL_STATIC_DRAW ) ;

glGenBuffers (1 ,& bufferTexCoord0 ) ;g lB indBu f fe r (GL_ARRAY_BUFFER, bufferTexCoord0 ) ;g lBu f fe rDa ta (GL_ARRAY_BUFFER,8∗ s i z e o f ( GLf loa t ) , tex tu re ,GL_STATIC_DRAW ) ;

}

Pour que le tracé soit fait avec les coordonnées de textures comme attributs de sommet :

. . .g l C l i e n t A c t i v e T e x t u r e (GL_TEXTURE0 ) ; / / on t r a v a i l l e avec l e premier jeu de coordonnées de t e x t u r e ( i . e . GL_TEXTURE0)g lEnab leC l i en tS ta te (GL_TEXTURE_COORD_ARRAY) ; / / a c t i v a t i o n de l ’ a l imen ta t i on du premier jeu de coordonnees de t e x t u r e

/ / ( i . e . a l imen ta t i on de gl_Mult iTexCoord0 dans l e ver tex shader ) .g lB indBu f fe r (GL_ARRAY_BUFFER, bufferTexCoord0 ) ;g lTexCoordPointer (2 ,GL_FLOAT, 0 , 0 ) ; / / données du premier jeu de coordonnées de t e x t u r e

glDrawArrays (GL_TRIANGLE_STRIP , 0 , 4 ) ;

g l C l i e n t A c t i v e T e x t u r e (GL_TEXTURE0 ) ;g l D i s a b l e C l i e n t S t a t e (GL_TEXTURE_COORD_ARRAY) ; / / dé sac t i ve l e premier jeu de coordonnées de tex tu res

A noter : possibilité d’avoir plusieurs jeux de coordonnées de textures gérées indépendamment(glClientActiveTexture(GL_TEXTUREi)).

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 52 / 58

Page 53: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Type sampler2D

I Dans les shaders, les images de texture sont accessibles gràce à des uniform de typesampler2D

Vertex Shader (se contente d’interpoler les coordonnées de texture) :

vary ing vec2 coordTex ;

void main ( ) {coordTex=gl_Mult iTexCoord0 . s t ; / / accès premier jeu de coordonnees

g l _ P o s i t i o n = g l _ P r o j e c t i o n M a t r i x∗gl_ModelViewMatr ix∗g l_Ver tex ;}

Fragment shader (récupération des coordonnées de texture interpolées et lecture de la couleurdans l’image) :

uni form sampler2D uneTexture ;

vary ing vec2 coordTex ;

void main ( ) {vec4 couleur ;cou leur=texture2D ( uneTexture , coordTex ) ;g l_FragColor = cou leur ;

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 53 / 58

Page 54: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Affectation de la texture depuis l’application

I On affecte l’uniform uneTexture avec l’unité de texture souhaitée.

glUseProgram ( monShader . i d ( ) ) ;GLuint locat ionSampler=glGetUni formLocat ion ( monShader . i d ( ) , " uneTexture " ) ; / / r écupé r e r où se t rouve " uneTexture " dans l e shaderg lUn i fo rm1 i ( locat ionSampler , 1 ) ; / / uneTexture correspondra à l ’ image de l ’ u n i t é de t e x t u r e 1

draw ( ) ;

glUseProgram ( 0 ) ;

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 54 / 58

Page 55: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Un exemple en multi-texture

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 55 / 58

Page 56: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Dans l’application

Quelques classes utilitaires pour alléger le code :

class GLView : . . . {. . .Shader _earthShader ;Texture _earthDay , _ear thNigh t ;Sphere _sphere ;. . .} ;

void GLView : : i n i t ( ) {earthDay . read ( " earthD . jpg " ) ;ea r thN igh t . read ( " earthN . jpg " ) ;

g lAc t i veTex tu re (GL_TEXTURE0 ) ;earthDay . bind ( ) ;g lAc t i veTex tu re (GL_TEXTURE1 ) ;ear thN igh t . b ind ( ) ;

sphere . i n i t B u f f e r ( ) ; / / géné r a t i o n sommets+coordonnées de tex tu res}

void draw ( ) {earthShader . enable ( ) ;earthShader . uni form ( " texJour " , 0 ) ;earthShader . uni form ( " t exNu i t " , 1 ) ;

sphere . drawBuffer ( ) ;

earthShader . d i sab le ( ) ;}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 56 / 58

Page 57: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Le vertex shader

Vertex :

vary ing vec2 texCoord ;vary ing vec3 normal ;vary ing vec3 L ;

void main ( ) {texCoord=gl_Mult iTexCoord0 . s t ;

/ / Source supposée d i r e c t i o n n e l l e i c i :L=gl_L ightSource [ 0 ] . p o s i t i o n . xyz ; / / dé j à exprimé dans l e repère Eye

normal=gl_NormalMatr ix∗gl_Normal ;

g l _ P o s i t i o n = g l _ P r o j e c t i o n M a t r i x∗gl_ModelViewMatr ix∗g l_Ver tex ;}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 57 / 58

Page 58: Chapitre 5 : Rendu projectif en OpenGL Vertex et Fragment shaders - Modélisation 3D ...aubert/m3ds/m3ds_shader.pdf · 2013. 2. 26. · Contenu du chapitre I Introduction aux techniques

Le fragment shader

Fragment :

uni form sampler2D texJour , t exNu i t ;

va ry ing vec2 texCoord ;vary ing vec3 normal ;vary ing vec3 L ;

void main ( ) {vec4 cou leurNu i t , cou leurJour ;vec3 normal2 , L2 ;normal2=normal ize ( normal ) ;L2=normal ize ( L ) ;f l o a t e c l a i r e =dot ( L2 , normal2 ) ;

/ / e c l a i r e=−1 : completement n u i t/ / e c l a i r e =1 : completement j o u re c l a i r e =( e c l a i r e + 1 . 0 ) / 2 . 0 ; / / i n t e r v a l l e [ 0 , 1 ]

cou leu rNu i t= texture2D ( texNu i t , texCoord ) ;cou leurJour=texture2D ( texJour , texCoord ) ;

/ / mélange t e x t u r e j o u r + n u i t (mélange t rop étendu i c i )gl_FragColor = couleurJour∗(1−e c l a i r e )+ cou leu rNu i t∗e c l a i r e ;

}

F. Aubert (MS2) M3DS/ Chapitre 5 : Shaders GLSL 2012-2013 58 / 58