Jump to content
  • Advertisement
Sign in to follow this  
The Blarg

Directional light transformation in a shader

This topic is 3242 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

I implement lighting in a shader that uses a directional light which I pass as a uniform. The problem is I can't figure out how to transform it into eye space so that the lighting doesn't follow the camera. This is my vertex shader:
uniform vec3 lightDir;
uniform float ambient;
uniform vec3 lightColour;

void main()
{
    gl_Position = ftransform();

    vec3 eyeNormal = normalize(gl_NormalMatrix * gl_Normal);
    // Multiplying by gl_ModelViewMatrix seems ineffectual.
    // I also tried multiplying by gl_NormalMatrix, which didn't work either.
    vec3 realLightDir = normalize(vec3(gl_ModelViewMatrix * vec4(lightDir, 0)));

    float intensity = max(ambient, dot(eyeNormal, realLightDir));

    vec4 lightColourV4 = vec4(lightColour, 1.0);

    gl_FrontColor = gl_Color * lightColourV4 * intensity;
}
And these are the steps I take each frame:
  1. Enable the shader
  2. Set the shader's uniform variables
  3. Set the projection matrix (glMatrixMode(GL_PROJECTION); glLoadIdentity(); Set my projection)
      I do this each frame since I switch between projections a lot, e.g. perspective for the scene, orthographic for the HUD
  4. Clear the modelview matrix (glMatrixMode(GL_MODELVIEW); glLoadIdentity();)
  5. Position the camera with gluLookAt
  6. Draw objects, rotating and translating as needed

Share this post


Link to post
Share on other sites
Advertisement
I had this exact same problem, and ended up getting more and more confused.

I suggest outputting your vectors after they are multiplied (meaning you have to do it outside of the shader). Also output each matrix at each stage.

It may sound tedious, but it will re-affirm any assumptions you might be making about how your calculations are going.

Also, make sure your handedness and things like that are correct.

vec3 eyeNormal = normalize(gl_NormalMatrix * gl_Normal);

this line confuses me a bit... what normal is this from? the object you are rendering?

Share this post


Link to post
Share on other sites
When passing the light direction how are you transforming it before you pass it as a uniform?
You might try doing your steps 3, 4, and 5 (camera related) first before anything else. Then setup lights and shaders, the draw transforms, then draw.

Share this post


Link to post
Share on other sites
If you position your objects with a matrix, this really needs a separate model and view matrix. The easiest way is probably to perform all your calculations in world-space, and with separate model and view matrices, you can ignore the view matrix for the (diffuse) lighting calculations.
You would declare this with uniform mat4 matView for example, in the shader, and set it with glUniformMatrix4fv.

Share this post


Link to post
Share on other sites
Well, isn't this confusing.

The light vector is specified in world space. I have done no transformation on it outside the shader.
The gl_Normal is from the object I'm rendering. All objects in my scene have normals for each vertex.

Setting the direction uniform after I do my transformations seem to have no effect.

So that you have a clearer picture, this is the actual code where I do the transformations:


// Set shader uniforms
// Light direction specified in world coordinates
...

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(fovY, aspect, near, far);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Camera follows a spaceship that flies over the ground at a fixed height of 0.333 units
// Camera is 2 units behind the ship and 1.333 units above the ground
double radians = shipAngle * (3.14 / 180.0);
gluLookAt(shipX - (2.0 * sin(radians)), 1.333, shipZ - (2.0 * cos(radians)), shipX, 0.333, shipZ, 0.0, 1.0, 0.0);

// Draw the ground, which is centred at the origin
...

// Position the ship
glTranslated(shipX, 0.333, shipZ);
glRotated(shipAngle, 0.0, 1.0, 0.0);

// Draw the ship
...

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!