• Advertisement
Sign in to follow this  

Lighting question in GLSL

This topic is 461 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone,

 

I have a simple GLSL shader I am working on (I have stripped down the original to illustrate the problem as clearly as possible).  I would like to have a single light source which is fixed relative to the scene.  Hence this line in my vertex shader:

 

    lightPos =   vec3(gl_ModelViewMatrix) *  vec3(-100.0,-0.0, 0.0);

 

The light source is defined at (-100.0,0.0,0.0) and since I am multiplying it by the modelview matrix I expect it to be remain fixed in the scene.  In other words, if I rotate the camera around, the light should also move relative to the camera.  This is not what I am getting.  The light source is always at the camera origin (appears to be 0,0,0).  When I rotate the camera around my object, the scene is always lit "head-on" so to speak.  I feel I am missing something fundamental.  

 

Would any of you be able to enlighten me?

 

Thank you

 

 

vertex shader:

 

varying vec3 normal;
varying vec3 vertex;
varying vec3 lightPos;
                    
void main()
{
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    normal = gl_NormalMatrix * gl_Normal;
            
    vertex =   gl_ModelViewMatrix * gl_Vertex;
    lightPos =   vec3(gl_ModelViewMatrix) *  vec3(-100.0,-0.0, 0.0);
}
 
frag shader:
 
varying vec3 normal;
varying vec3 vertex;
varying vec3 lightPos;
              
void main()
{
    const vec4 DiffuseColor = vec4(1.0, 0.0, 0.0, 1.0);
 
    vec3 position2light=normalize(lightPos-vertex);
    vec3 norm=normalize(normal);
  
    // Calculating The Diffuse Term And Clamping It To [0;1]
    float DiffuseTerm = clamp(dot(norm, position2light), 0.0, 1.0);
 
    gl_FragColor = DiffuseColor * DiffuseTerm; 
}
 
 

Share this post


Link to post
Share on other sites
Advertisement
Awesome! Just note that this calculation will actually put your light (-100,0,0) units from the object you are currently rendering.

If you want the light to be located at (-100,0,0) in world space, so it has the same position for all objects in your scene, then you want to do:

LightPosEyeSpace = view matrix * LightPosWorldSpace

Share this post


Link to post
Share on other sites

Thanks for clarifying that!  Where does the view matrix come from?  Is it built into glsl or do I need to calculate it and pass it from the CPU? 

Share this post


Link to post
Share on other sites
The modelview matrix is actually two transformations concatenated into one, the model transformation which places your object in the world and the view transformation which puts the world space object relative to the camera.

The view matrix is often created using a "look at" function, like gluLookAt for example.

If you want to do your lighting in eye space, you'll need to use that view matrix to transform the light's position into eye space.
You could send the view matrix to glsl as a uniform and do the transformation in the vertex shader, but if you think about it, the view matrix and light position are going to be the same for all of the vertices, aren't they? So what you could do instead is transform the light position into eye space just once cpu side and then send the transformed position as uniform. Either way will work but the latter saves you a per vertex matrix multiplication.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement