Skip to main content
GameDev.net gamedev.net
🔒 Locked

GLSL lighting problem (normals)

Started by assainator Nov 21, 2011 at 7:03 PM 4 replies 2.6k views
Original Post
assainator
assainator
Hello,

Last week I've run into a problem but can't find what's causing the problem.

The problem is as follows. I have a sphere and a light source. When the sphere isn't rotated, the lighting looks fine:
yaagelightrot0.jpg

But as soon as I try to rotate it, the lighting get's all wrong. The picture below shows the sphere when it's rotated 90 degrees around the y-axis.
yaagelightrot90.jpg


My first thought is that for some reason the normals aren't rotated at all or not rotated correctly.

I'm using GLSL and OpenGL 2.

I think shaders sources are useful:
vertex shader
[source]
// The diffuse value
varying float diffuse_value;

// The normalized light position
uniform vec3 NormalizedLightDirection;

void main()
{
// Calculate the actual normal
vec3 vertex_normal = normalize(gl_Normal * gl_NormalMatrix);

// Calculate the diffuse value
diffuse_value = max(dot(vertex_normal, NormalizedLightDirection), 0.0);

// Set vertex position
gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex);

gl_FrontColor = gl_Color;
}
[/source]

fragment shader:
[source]
varying float diffuse_value;

uniform vec4 DiffuseColor;

void main()
{
// Set the final color by multiplying the diffuse color with the diffuse value and then adding the ambient lighting
gl_FragColor = vec4(1.0) * diffuse_value;
}
[/source]

I appreciate any advice anybody can give me.
"What? It disintegrated. By definition, it cannot be fixed." - Gru - Dispicable me

"Dude, the world is only limited by your imagination" - Me

SaTANO
SaTANO
Correct this
vec3 vertex_normal = normalize(gl_NormalMatrix * gl_Normal );
OpenGL use column major matrices (same as your gl_Position calculation)
Burnt_Fyr
Burnt_Fyr

Hello,

Last week I've run into a problem but can't find what's causing the problem.

The problem is as follows. I have a sphere and a light source. When the sphere isn't rotated, the lighting looks fine:
yaagelightrot0.jpg

But as soon as I try to rotate it, the lighting get's all wrong. The picture below shows the sphere when it's rotated 90 degrees around the y-axis.
yaagelightrot90.jpg


My first thought is that for some reason the normals aren't rotated at all or not rotated correctly.

I'm using GLSL and OpenGL 2.

I think shaders sources are useful:
vertex shader
[source]
// The diffuse value
varying float diffuse_value;

// The normalized light position
uniform vec3 NormalizedLightDirection;

void main()
{
// Calculate the actual normal
vec3 vertex_normal = normalize(gl_Normal * gl_NormalMatrix);

// Calculate the diffuse value
diffuse_value = max(dot(vertex_normal, NormalizedLightDirection), 0.0);

// Set vertex position
gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex);

gl_FrontColor = gl_Color;
}
[/source]

fragment shader:
[source]
varying float diffuse_value;

uniform vec4 DiffuseColor;

void main()
{
// Set the final color by multiplying the diffuse color with the diffuse value and then adding the ambient lighting
gl_FragColor = vec4(1.0) * diffuse_value;
}
[/source]

I appreciate any advice anybody can give me.


Your Normalized light direction should be in the same space as the normal, and is not the direction the light is facing, but the direction from point to light. assuming that the gl_Normal matrix is the matrix translating from object space to world space, and that Normalized Light Direction is the vector that a directional light is pointing, use the inverse.

[source]
diffuse_value = max(dot(vertex_normal, -NormalizedLightDirection), 0.0);
[/source]

if that doesn't work, check your gl_NormalMatrix to be sure that it is indeed what it should be. (identity for an object with no transforms, or a rotation matrix if you do have some)
dpadam450
dpadam450
// Calculate the actual normal vec3 vertex_normal = normalize( gl_NormalMatrix* gl_Normal);
NormalizedLightDirection = normalize( gl_NormalMatrix* NormalizedLightDirection); // Calculate the diffuse value diffuse_value = max(dot(vertex_normal, NormalizedLightDirection), 0.0);
NBA2K, Madden, Maneater, Killing Floor, Sims 
assainator
assainator

Correct this
vec3 vertex_normal = normalize(gl_NormalMatrix * gl_Normal );
OpenGL use column major matrices (same as your gl_Position calculation)


That did the trick!

Thanks a lot for all the replies.
"What? It disintegrated. By definition, it cannot be fixed." - Gru - Dispicable me

"Dude, the world is only limited by your imagination" - Me

Burnt_Fyr
Burnt_Fyr

Correct this
vec3 vertex_normal = normalize(gl_NormalMatrix * gl_Normal );
OpenGL use column major matrices (same as your gl_Position calculation)


!FACEPALM

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.