Bonsoir, je viens récemment de mettre en oeuvre le chargement de shaders dans une application OpenGL
Et bien sûr j'ai voulu tester immédiatement avec une émulation du pipeline fixe : l'éclairage Phong
Dans le code de l'application j'opère tous les calculs de matrices moi-même à l'aide de la librairie de maths GLM, donc aucun appel à la pile de matrices d'OpenGL, je gère le lookat et les transformations tout seul
Puis je passe les matrices de projection, modelview, normalmatrix ainsi que la position d'une lumière (LightPos) au shader phong via des variables uniform
Résultat sur un cube, cela me semble correct, à un détail près, la position de la lumière est "collée" à celle de la caméra
Après quelques recherches j'apprends que la position de la lumière doit être transposée de l'espace world à l'espace caméra (ou bien l'inverse j'ai pas trop compris)
il me faudrait donc appliquer la variable LightPos une multiplication de matrice
j'ai essayé avec modelview, positionMatrix, normalMatrix, rien ne change à quelques détails près
je sais que c'est que c'est dans le vertex shader que je dois ajouter ou corriger quelque chose mais je suis bloqué, là
Voici le code du shader :
VERTEX_SHADER
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 uniform vec4 LightPos; uniform mat4 ModelViewMatrix; uniform mat4 ProjectionMatrix; uniform mat3 NormalMatrix; varying vec3 normal, lightDir, eyeVec; //attribute vec3 tangent; void main() { //vec3 lightposition = vec3(ModelViewMatrix * vec4(0.0, 0.0, 45.0,0.0)); normal = NormalMatrix * gl_Normal; //normal = gl_NormalMatrix * gl_Normal; vec3 vVertex = vec3(ModelViewMatrix * gl_Vertex); //vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex); //lightDir = vec3(gl_LightSource[0].position.xyz - vVertex); lightDir = normalize(LightPos.xyz - vVertex); //lightDir = normalize(lightposition - vVertex); eyeVec = normalize(-vVertex); gl_Position = ProjectionMatrix*ModelViewMatrix*gl_Vertex; //gl_Position = gl_ProjectionMatrix*gl_ModelViewMatrix*gl_Vertex; }
(je récupère les paramètres ambient, diffuse depuis une glLight built-in, je ne pense pas que ça change quoique ce soit)
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 varying vec3 normal, lightDir, eyeVec; void main (void) { vec4 final_color = (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) + (gl_LightSource[0].ambient * gl_FrontMaterial.ambient); vec3 N = normalize(normal); vec3 L = normalize(lightDir); float lambertTerm = dot(N,L); if(lambertTerm > 0.0) { final_color += gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * lambertTerm; vec3 E = normalize(eyeVec); vec3 R = reflect(-L, N); float specular = pow( max(dot(R, E), 0.0), gl_FrontMaterial.shininess ); final_color += gl_LightSource[0].specular * gl_FrontMaterial.specular * specular; } gl_FragColor = final_color; }
Et voici une capture du "phénomène" :
le cube au centre est l'objet éclairé et la "boîte" bleue représente la position de la lumière, on voit sur la fin que la tâche spéculaire "suit" le mouvement de la caméra
(la vidéo est super rapide, j'ai pas fait dans le détail)
Partager