PDA

View Full Version : Problem with normal mapping. (Fragment position)



Lolilolight
07-20-2014, 02:23 AM
Hi, I'm trying to set up a shader for normal mapping in a 2D context.

This following image show what I'm trying to do :

1370

The normal map contains the normals of my tiles, and their height.

I transform the light position to screen coordinates, to have the vector between the light position and the fragments of my tiles.

The first problem is that I use 0, 0 as up left corner, and opengl use 0,0 as low left corner.
Is there an equivalent to this in GLSL 1.3 ?


layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;


Here's the code of my fragment shader :



const std::string perPixLightingFragmentShader =
"#version 130 \n"
"uniform sampler2D normalMap;"
"uniform vec3 resolution;"
"uniform vec4 lightColor;"
"uniform sampler2D lightMap;"
"uniform vec4 lightPos;"
"in mat4 projMat;"
"void main () { "
"vec2 position = (gl_FragCoord.xy / resolution.xy);"
"vec4 bump = texture2D(normalMap, position);"
"vec4 cBump = inverse(projMat) * vec4(0, 0, bump.w, 0);"
"vec3 pixPos = vec3 (gl_FragCoord.x, cBump.z, resolution.y - gl_FragCoord.y);"
"vec4 lightMapColor = texture2D(lightMap, position);"
"vec3 nLightPos = vec3 (lightPos.x, lightPos.z, lightPos.y);"
"float radius = lightPos.w;"
"if (gl_FragCoord.z >= bump.w && distance(pixPos, nLightPos) <= radius) {"
"vec3 vertexToLight = nLightPos - pixPos;"
"float attenuation = 1.0f - (length(vertexToLight) / radius);"
"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;"
"}"
"}";


But it gives me a strange result :

https://www.youtube.com/upload

Hmfff..., maybe I've found why, the z position is the y center of the tiles, so, sometimes the fragment is on one side and sometimes he's on the other side of the light.

So, I need to find a way to handle this problem but I don't see how.

Lolilolight
07-20-2014, 03:54 AM
I've tried this :



const std::string perPixLightingFragmentShader =
"#version 130 \n"
"uniform sampler2D normalMap;"
"uniform vec3 resolution;"
"uniform vec4 lightColor;"
"uniform sampler2D lightMap;"
"uniform vec4 lightPos;"
"in mat4 projMat;"
"void main () { "
"vec2 position = vec2 (gl_FragCoord.x / resolution.x, (resolution.y - gl_FragCoord.y) / resolution.y);"
"vec4 bump = texture2D(normalMap, position);"
"vec4 cBump = inverse(projMat) * vec4(0, 0, bump.w, 0);"
"vec3 pixPos = vec3 (gl_FragCoord.x, cBump.z, resolution.y - gl_FragCoord.y);"
"vec4 lightMapColor = texture2D(lightMap, position);"
"vec3 nLightPos = vec3 (lightPos.x, lightPos.z, lightPos.y);"
"float radius = lightPos.w;"
"if (gl_FragCoord.z >= bump.w && distance(pixPos, nLightPos) <= radius) {"
"vec3 vertexToLight = nLightPos - pixPos;"
"float attenuation = 1.0f - (length(vertexToLight) / radius);"
"if (bump.x != 0 || bump.y != 0 || bump.z != 0) {"
"vec3 dirToLight = normalize(vertexToLight.xyz);"
"float nDotl = abs(dot (dirToLight, bump.xzy));"
"attenuation *= nDotl;"
"}"
"gl_FragColor = lightColor * max(0.0f, attenuation);"
"} else {"
"gl_FragColor = lightMapColor;"
"}"
"}";


But it doesn't work better.