Vertex lighting shader - black dot at rendering

Good morning,

I am doing my first steps in shader coding using GLSL. For a start I wanted to create a lighting algorithm, so I browsed the internet and found some fairly simple examples. To suit my need I only changed the lights by adding my own custom ones, as uniform variables. Here the code:

// The shader is creating the light effects on a sphere
// from several light sources.
uniform vec3 Sphere_Position;
uniform int Light_Counter;
uniform vec3 Light_Position[20];
uniform vec3 Light_Color [20];
uniform float Light_Factor [20];

// Main function
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;

for(int i = 0; i < Light_Counter; i ++)
{
vec3 Light_Direction = -normalize(gl_Position.xyz - Light_Position[i].xyz);
vec3 Vertex_Normal = normalize(gl_NormalMatrix * gl_Normal);
float Dot_Product = max(dot(Vertex_Normal, Light_Direction), 0.0);

float Light_Distance = length(gl_Position.xyz - Light_Position[i].xyz);
float Final_Factor = (Dot_Product * Light_Factor[i]) / (Light_Distance * Light_Distance);

gl_FrontColor.xyz = gl_FrontColor.xyz * Light_Color[i].xyz * Final_Factor;
}

Now as the title suggest, when rendering, this produces a nice light/shadow effect, except for a small black circle zone in the middle of the sphere… Sounds to me like a very basic geometry principle, but I can’t figure it out!

Any help would be very much appreciated!

Thank you,

Philippe

EDIT: I forgot to mention that to first keep it simple, I am testing with a single light. So the ‘for’ loop can be neglect for the moment!

You need to make sure all of your vectors are in the same coordinate space. Your vertex positions are in clipspace but I am not sure which space your light position is (usually it is in eye space) but I cant tell.

Thank you for your answer Mobeen. I think I understand what you’re saying, but I am not yet familiar enough with those concepts: my light position is sent by the program (hence the uniform variable). So as you can imagine, I have a ‘Light’ class with a ‘Position’ property sent to the shader before rendering.
Same principle is applied for the Sphere position (or center) used by my shader.

What coordinate space would that be?

Typical I am testing with the following code:

gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

// Draw the lamp without shader
glPushMatrix();
glTranslatef(3.0f, 3.0f, 5.0);
// Draw light source
glPopMatrix();

// Activate the shader and set variables
vshader.Activate();
// Define the current sphere properties
vshader.SetUniform3f(“Sphere_Position”, -1.0f, 0.0f, 0.0f);
vshader.SetUniform3f(“Light_Position[0]”, 3.0f, 3.0f, 5.0f);
vshader.SetUniform3f(“Light_Color[0]”, 1.0f, 1.0f, 0.8f);
vshader.SetUniform1f(“Light_Factor[0]”, 50.0f);
// Activate lights
vshader.SetUniform1i(“Light_Counter”, 1);

glPushMatrix();
glTranslatef(-1.0f, 0.0f, 0.0);
// Draw sphere
glPopMatrix();

EDIT: Your remark made me tried something: I used the ‘gl_Vertex’ instead of the transformed ‘gl_Position’. Render obviously change and I would need to analyse it more further to understand, but interesting points are:

  • I still have a nice shadow/light gradient effect (might be an unrealistic one, but still)
  • The black circle has turned into a white one, but is still there

I found my mistake:

In my vertex shader, first instruction was this:
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

This is the correct transformation to finally apply on gl_position, however, I am first using it to calculate the lighting effect… And that is where your remark makes sense, Mobeen!

Solution is therefore this:

// First calculate de position in the correct coordinate space
gl_Position = gl_ModelViewMatrix * gl_Vertex;

// … Lighting calculation using gl_Position

// Then apply the final transformation on the point
gl_Position = gl_gl_ModelViewProjectionMatrix * gl_Vertex;

Thanks again for having pointed me in the right direction.

Philippe

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.