Search code examples
openglglsllighting

Light Direction and its Transformation in the Simplest Lighting Model


So, I've gotten to basic lighting in my OpenGL learning quest.

Imagine this simplest lighting model. Each vertex has a position, color, and normal. The shader gets the ModelViewProjection matrix (MVP), Modelview matrix(MV) , and Normal matrix (N) which calculated as (MV-1)T, as well as LightColor and LightDirection as uniforms. The vertex shader performs the lighting calculations - the fragment shader just outputs the interpolated colors.

Now, in every tutorial on this subject I have come across I see two things that puzzle me. First, the LightDirection is already assumed to be in eye coordinates. Second, the output color is calculated as

max(0, dot(LightDirection, N * normal))*LightColor*Color;

I would expect that the LightDirection should be inversed first, that is, the correct formula I would think is

max(0, dot(-LightDirection, N * normal))*LightColor*Color;

It seems that it is assumed that the LightDirection is actually the reverse of the vector of the actual light flow.

Q1: Is this some sort of established convention that the LightDirection in this model is assumed to be the vector to the infinitely far light source rather than the vector of the light direction or is this not a principal matter and it just so happened that in the tutorials I came across it was so assumed?

Q2: If LightDirection is in world coordinates rather than in eye coordinates, should it be transformed with the normal matrix or the modelview matrix to eye coordinates?

Thanks for clarifying these things!


Solution

  • Q1: Is this some sort of established convention that the LightDirection in this model is assumed to be the vector to the infinitely far light source rather than the vector of the light direction or is this not a principal matter and it just so happened that in the tutorials I came across it was so assumed?

    In fixed function OpenGL when supplying the position of the light, the 4th parameter determined if the light was directional or positional. In the case of directional light, the vector supplied points towards the (infinitely far away) light source.

    In case of a positional light source, LightDirection is computed per vertex as LightDirection = LightPosition - VertexPosition -- for the sake of simplicity this calculation is done in eye coordinates.

    Q2: If LightDirection is in world coordinates rather than in eye coordinates, should it be transformed with the normal matrix or the modelview matrix to eye coordinates?

    In fixed function OpenGL the light position supplied through glLighti was transformed by the at call time current modelview matrix. If the light was positional, it got transformed by the usual modelview matrix. In case of a directional light, the normal matrix was used.