Bonjour, j'ai écrit un petit shader qui calcule la matrice TBN et qui fait le bump mapping
la nouveauté par rapport aux codes trouvés sur google est que l'on peut utiliser la matrice GL_TEXTURE
j'aimerais que vous me disiez ce que vous en pensez, et également que vous me donniez des conseils pour en faire une version plus "élégante"
voici le vertex shader:
et le fragment shader:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 attribute vec3 A,B,C; attribute vec2 ta,tb,tc; varying vec3 L, LE; void main(void) { gl_Position = ftransform(); gl_FrontColor = gl_Color; // A,B,C are vertex coordinates of the triangle // ta,tb,tc are texture coordinates of the triangle vec3 AB = B - A; vec3 AC = C - A; vec2 tab = tb - ta; vec2 tac = tc - ta; // we multiply the texture matrix with tab and tac tab = gl_TextureMatrix[0] * vec4(tab,0,1); tac = gl_TextureMatrix[0] * vec4(tac,0,1); // let's get the tangeant and the binormal direction float coef = 1.0 / (tac.y*tab.x - tab.y*tac.x); vec3 tangeant = (tac.y*AB - tab.y*AC)*coef; vec3 binormal = -(tac.x*AB - tab.x*AC)*coef; // let's normalize and pass tangeant, binormal normal into eye coordinates tangeant = normalize(gl_NormalMatrix * tangeant); binormal = normalize(gl_NormalMatrix * binormal); vec3 normal = normalize(gl_NormalMatrix * gl_Normal); // we now have our TBN matrix (eye to local transform) mat3 TBN = mat3(tangeant,binormal,normal); // vertex to eye vector vec3 toE = - gl_ModelViewMatrix * gl_Vertex; // vertex to light vector vec3 toL = toE + gl_LightSource[0].position; // half vector to eye, to light vec3 toLE = normalize(normalize(toL) + normalize(toE)); // let's pass toL and toLE into TBN coordinates L = normalize(toL * TBN); LE = normalize(toLE * TBN); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; }
le principe est que l'on envoie au shader des attributes:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 uniform sampler2D tex; uniform sampler2D normal_map; varying vec3 L, LE; const float ambient = 0.3; const float diffuse = 1.6; const float specular = 0.5; const float exp_specular = 10; void main() { vec3 N = texture2D(normal_map,gl_TexCoord[0].st)*2.0 - 1.0; // normal_map has already been normalized // normalize(N); L = normalize(L); LE = normalize(LE); float NdotL = max(dot(N,L),0.0); float NdotLE = max(dot(N,LE),0.0); vec4 color = texture2D(tex,gl_TexCoord[0].st); gl_FragColor = color * (ambient + NdotL * diffuse) + vec4(1,0,0,0)*specular*pow(NdotLE,exp_specular); }
les coordonnées des 3 vertex (attribute vec3 A,B,C)
les coordonnées de textures des 3 sommets (vec2 ta,tb,tc)
à partir de ça on peut calculer la matrice TBN
pour être plus clair voici le code utilisé pour dessiner le triangle:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 glBegin(GL_TRIANGLES); glVertexAttrib3f(ind_A,-1,-1,0); glVertexAttrib3f(ind_B,-1,1,0); glVertexAttrib3f(ind_C,1,1,0); glVertexAttrib2f(ind_ta,0,0); glVertexAttrib2f(ind_tb,0,1); glVertexAttrib2f(ind_tc,1,1); glTexCoord2f(0,0); glVertex3f(-1,-1,0); glTexCoord2f(0,1); glVertex3f(-1,1,0); glTexCoord2f(1,1); glVertex3f(1,1,0); glEnd();
Partager