I am attempting to create a GLSL shader for simple, per-fragment directional light. So far, after following many tutorials, I have continually ran into the issue: my light is specified in world coordinates, however, the shader treats the light's position as being in eye space, thus, the light direction changes when I move the camera. My question is, how to I transform a directional light position such as (50, 50, 50, 0) into eye space, or, would doing things this way be the incorrect approach to the problem?


You have two options. The easiest in my opinion for a variety of reasons is to just multiply your light data by the view/camera matrix so that they're in view space.

The second option is that in your vertex shader you can generate outputs multiplied by only the model transformation matrix in addition to the usual fully projected outputs (similar to how you can generate outputs with only the model and view matrices to get outputs in view space).

Yet another option is to take the NDC-space data you have in the fragment shader and the inverse of your projection and view matrices to recalculate world-space coordinates. Just remember that you need to do the whole W divide step as NDC-space is more than just a transformation by the projection matrix.

I personally just calculate light data in view-space and add extra outputs to the vertex shader which are in eye-space, since it makes the math easier and slightly faster (you generally don't have enough lights to make the matrix multiplication on the CPU be a big deal, and with a deferred shader pipeline, you can do it on the GPU anyway).

  • \$\begingroup\$ So, by light data, I would understand that to be the direction; IE. doing modelview * light_pos on the CPU side, correct? \$\endgroup\$ – Outurnate Jun 29 '13 at 20:46
  • \$\begingroup\$ Not model view, but your camera matrix. The light had no relation to your model. You also need to transform the lights position for point and spot lights. \$\endgroup\$ – Sean Middleditch Jun 29 '13 at 21:07
  • \$\begingroup\$ Ah! Does the camera matrix include the frustrum? \$\endgroup\$ – Outurnate Jun 29 '13 at 21:32
  • \$\begingroup\$ It's implicitly part of the concatenated camera and projection matrices. One quick Google search gives the following page, unsure how good it is: lighthouse3d.com/tutorials/view-frustum-culling \$\endgroup\$ – Sean Middleditch Jun 29 '13 at 21:43

I followed Sean Middleditch's advice to solve my directional light issue which was the same as the OP. ( I can't vote yet )

In glm i used the following code to solve my problem;

_view  = glm::lookAt(glm::vec3(3, 3, 3), glm::vec3(0), glm::vec3(0,1,0));
// send this to uniform location.
glm::mat3 v(_view); 

In my shader i just did the following

lightDir = normalize(view * lightDir);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.