Salut, j'essaye d'effectuer un rendu par pixel de la lumière à l'aide d'une normal map.
Les composantes rgb de la normale map contiennent les composantes x, y et z des normales (vecteurs perpendiculaires à mes tiles) et la composante w contient la hauteur du fragment. (que je défini moi même)
J'envoie la position de la lumière : x et y contiennent la position de la lumière, z la hauteur de la lumière et j'envoie dans la composante w le rayon de la lumière, j'envoie donc la lumière comme ceci à mon fragment shader :
perPixLightingShader->setParameter("uLightPos", el->getCenter().x, el->getCenter().y, el->getCenter().z, el->getSize().x);
perPixLightingShader->setParameter("lightColor", el->getColor().r, el->getColor().g,el->getColor().b,el->getColor().a);
Je transforme ensuite la position de la lumière dans le vertex shader pour l'avoir en coordonnées écran dans le fragment
shader :
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 "#version 130 \n" "uniform vec4 uLightPos;" "out vec4 lightPos;" "void main () {" "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;" "gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;" "gl_FrontColor = gl_Color;" "lightPos = gl_ModelViewMatrix * uLightPos;" "lightPos.w = uLightPos.w;" "}";
Le problème survient dans le fragment shader, la distance entre la position de la lumière et le pixel courant est toujours > au rayon et je ne comprends vraiment pas pourquoi :
Code cpp : 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 const std::string perPixLightingFragmentShader = "#version 130 \n" "uniform sampler2D normalMap;" "uniform vec3 resolution;" "uniform vec4 lightColor;" "uniform sampler2D lightMap;" "in vec4 lightPos;" "void main () { " "vec2 position = ( gl_FragCoord.xy / resolution.xy );" "vec4 bump = texture2D(normalMap, position);" "vec3 pixPos = vec3 (gl_FragCoord.x, gl_FragCoord.y, bump.a);" "vec4 lightMapColor = texture2D(lightMap, position);" "float ray = lightPos.a;" "if (gl_FragCoord.z >= bump.a && distance(lightPos.xyz, pixPos) <= ray) {" "vec3 vertexToLight = lightPos.xyz - pixPos;" "float attenuation = 1.0f - (length(vertexToLight) / ray);" "if (bump.x != 0 || bump.y != 0 || bump.z != 0) {" "vec3 dirToLight = normalize(vertexToLight.xyz);" "float nDotl = dot (dirToLight, bump.xzy);" "attenuation *= nDotl;" "}" "gl_FragColor = lightColor * max(0.0f, attenuation);" "} else {" "gl_FragColor = lightMapColor;" "}" "}";
Je pense que gl_FragCoord et lightPos ne sont pas dans le même repère, pourtant gl_FragCoord devrait donner la position du fragment par rapport au coin supérieur gauche de la fenêtre non ?
Partager