Question

I have a normal map in my OpenGL game engine and I realized that my normal map shader (and parallax map shader for that matter) have a problem with the lighting. Regardless of where the light is,the light always comes from the right. I am using a tangent space shader and I'm not sure if what I am passing in is correct.

This is the Normal Map That I Am Using: The Normal Map I am using

And here is the render:

Rendered Image

The light appears to be coming from the coordinate 3,0,3 but its actual location is -3,0,3

Any Ideas.

Shaders:

[vert]

attribute vec3 intan;

varying vec3 lightDir;
varying vec3 viewDir;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;

vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);

vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * intan);
vec3 b = cross(n, t) ;

mat3 tbnMatrix = mat3(t.x, b.x, n.x,
                      t.y, b.y, n.y,
                      t.z, b.z, n.z);

lightDir = (gl_LightSource[1].position.xyz - vertexPos) / 1000.;
lightDir = tbnMatrix * lightDir;

viewDir = -vertexPos;
    //viewDir = 
viewDir = tbnMatrix * viewDir;
}

[frag]

uniform sampler2D tex;
uniform sampler2D nor;

varying vec3 lightDir;
varying vec3 viewDir;

const vec4 d = vec4(0.19225,0.19225,0.19225,1.0);
const vec4 a = vec4(0.50754,0.50754,0.50754,1.0);
const vec4 s = vec4(0.508273,0.508273,0.508273,1.0);

void main()
{
vec3 l = lightDir;
float atten = max(0.0, 1.0 - dot(l, l));

l = normalize(l);

vec3 n = normalize(texture2D(nor, gl_TexCoord[0].st).xyz * 2.0 - 1.0);
vec3 v = normalize(viewDir);
vec3 h = normalize(l + v);

float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);

vec4 ambient = a * atten;
vec4 diffuse = d * nDotL * atten;
vec4 specular = s * power * atten;
vec4 color = ambient + diffuse + specular;

gl_FragColor = color * texture2D(tex, gl_TexCoord[0].st);
}
Was it helpful?

Solution

vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * intan);
vec3 b = cross(n, t) ;

I suppose intan designates the direction in which the normal map "right" points. Then that cross product is wrong. If n points out of the surface and intan to the right, then b(inormal) points downwards.

Note that it makes no difference if you transform normal and tangent and then do the crossproduct of the result or do the crossproduct first and transform the result.

lightDir = (gl_LightSource[1].position.xyz - vertexPos) / 1000.;

Why don't you just normalize that? That division by 1000 doesn't make sense.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top