overTaker

02-05-2014, 10:00 AM

Hello.

I am trying to implement simple directional lightning. While simple diffuse is easy thing to do, the problems come with specular component.

When viewer (camera) moves, the specular highlight is supposed to move with it. The problem is that, I can't achieve that effect.

I have read, the correct thing to do is just multiply the normal by normal matrix, and the normal matrix is just inversed and transposed ModelView matrix.

While I'm using GLM library, i get View matrix by calling glm::LookAt with specified parameters, and multiply it with my model's matrix to get the modelview matrix. That matrix, named NMTX in shaders is sent as uniform and is multiplied with normal in vertex shader like this:

fragmentNormal = normalize(NMTX * vertexNormal);

Then, fragmentNormal is being sent to fragment shader:

vec3 normal = fragmentNormal;

vec3 col = texture(tex, fragmentUV).rgb;

vec3 scatteredLight = vec3(0.0f);

vec3 reflectedLight = vec3(0.0f);

...

vec3 direction = normalize(lights[i].position + lights[i].target);

float diffuse = max(0.0f, dot(normal, direction));

float specular = max(0.0f, dot(normal, lights[i].halfwayVector));

if (diffuse == 0) specular = 0;

else specular = pow(specular, Shininess) * lights[i].strength;

scatteredLight += ambientLight + lights[i].color * diffuse;

reflectedLight += lights[i].color * specular;

...

outColor = reflectedLight;

This code generates the specular highlights fine, but they only change when the camera rotates. I am aware as this may be coordinate space issue, as light direction and halfway vector are in model coordinates, and normals are in eye coordinates (after multiplying by the matrix in vertex shader). I tried to overcome that by multiplying theese two vectors by normal matrix too, but then the specular highlight just went completely static.

Ignoring performance issues in the above shaders (as I just want to understand the issue I described), what am I doing wrong?

I am trying to implement simple directional lightning. While simple diffuse is easy thing to do, the problems come with specular component.

When viewer (camera) moves, the specular highlight is supposed to move with it. The problem is that, I can't achieve that effect.

I have read, the correct thing to do is just multiply the normal by normal matrix, and the normal matrix is just inversed and transposed ModelView matrix.

While I'm using GLM library, i get View matrix by calling glm::LookAt with specified parameters, and multiply it with my model's matrix to get the modelview matrix. That matrix, named NMTX in shaders is sent as uniform and is multiplied with normal in vertex shader like this:

fragmentNormal = normalize(NMTX * vertexNormal);

Then, fragmentNormal is being sent to fragment shader:

vec3 normal = fragmentNormal;

vec3 col = texture(tex, fragmentUV).rgb;

vec3 scatteredLight = vec3(0.0f);

vec3 reflectedLight = vec3(0.0f);

...

vec3 direction = normalize(lights[i].position + lights[i].target);

float diffuse = max(0.0f, dot(normal, direction));

float specular = max(0.0f, dot(normal, lights[i].halfwayVector));

if (diffuse == 0) specular = 0;

else specular = pow(specular, Shininess) * lights[i].strength;

scatteredLight += ambientLight + lights[i].color * diffuse;

reflectedLight += lights[i].color * specular;

...

outColor = reflectedLight;

This code generates the specular highlights fine, but they only change when the camera rotates. I am aware as this may be coordinate space issue, as light direction and halfway vector are in model coordinates, and normals are in eye coordinates (after multiplying by the matrix in vertex shader). I tried to overcome that by multiplying theese two vectors by normal matrix too, but then the specular highlight just went completely static.

Ignoring performance issues in the above shaders (as I just want to understand the issue I described), what am I doing wrong?