eye space or world space?

It’s perhaps a stupid question but when using gl_arb_vertex_program and declaring a parameter like this :

PARAM lightDir = state.light[0].position;

in which space the light position is? It is not explained in the spec. And what about light half as well?


Without looking at the spec, I’m pretty sure it’s in eye space, since that is what GL stores internally.

It seems like the position is in world space, I tried a little program that includes this line : MOV oColor.xyz, light_dir; I can move in my scene without a vertex color change. So it isn’t in eye space.


What I meant was, it’s the same value that GL stores internally when you specify the light position with glLight(GL_POSITION,…). That position gets transformed by the modelview matrix and stored internally, when glLight gets called. That’s the value you’ll get in your vertex program. Of course it won’t change if, after having called glLight, you change your modelview matrix, just like with lights in the fixed-function GL pipeline.

I’m may be wrong but if you move the camera (and so the modelview change), the direction of the light in eye space change (whereas it doesn’t change in world space of course), does it? So if the vertex output color is equal to the light direction in eye space, the color of the vertex should change when the camera move, no?


No, consult the OpenGL spec about setting a light position with glLight. If you want the light position to change you have to call glLight every time you change the modelview matrix.

I shift my light position setting between the camera beginupdate and endupdate, and I still got the same result… strange, besides the example in the spec of gl_arb_vertex_program calculate lighting in eye space and it doesn’t work well in my engine (the light move with camera whereas the light doesn’t move in the world). My light position setup fonction should be bugged.



Is it me, or are you looking for the light’s direction, not the position? Instead of

MOV oColor.xyz, light_dir;

You would want something like

ADD oColor.xyz, light_dir, -v[0];

And of course you would want the color to be normalized and range compressed, but you get the idea. I don’t think that state.light[0].position is really the ‘lightDir’ you want it to be. Observe the light state table…

Light Property Bindings

  Binding                        Components  Underlying State
  -----------------------------  ----------  ----------------------------
  state.light[n].ambient         (r,g,b,a)   light n ambient color
  state.light[n].diffuse         (r,g,b,a)   light n diffuse color
  state.light[n].specular        (r,g,b,a)   light n specular color
  [b]state.light[n].position        (x,y,z,w)   light n position[/b]

Now here is what is extremely confusing, take a look at (73) …

PARAM lightDir = state.light[0].position;

Compute diffuse and specular dot products and use LIT to compute

lighting coefficients.

DP3 dots.x, xfNormal, lightDir;
DP3 dots.y, xfNormal, halfDir;
MOV dots.w, specExp.x;
LIT dots, dots;

My 2 cents are

A - According to the light properties, ‘lightDir’ is not the light’s direction, it is it’s position, so why isn’t there a/an ADD/SUB command and an accompanying normalization of the vector?

B - I believe state.light[i].position is stored in eye space because in that example shader, ‘lightDir’ is not modified by any matricies.


[This message has been edited by Dan82181 (edited 09-22-2002).]

Ok guys, to clear this up, here a quote from MSDN when calling glLight(GL_POSITION,…):

The position is transformed by the modelview matrix when glLight is called (just as if it were a point), and it is stored in eye coordinates. If the w component of the position is 0.0, the light is treated as a directional source. Diffuse and specular lighting calculations take the lights direction, but not its actual position, into account, and attenuation is disabled. Otherwise, diffuse and specular lighting calculations are based on the actual location of the light in eye coordinates, and attenuation is enabled. The default position is (0,0,1,0); thus, the default light source is directional, parallel to, and in the direction of the –z axis.

And then a quote from glGetLight(GL_POSITION,…):

The returned values are those maintained in eye coordinates. They will not be equal to the values specified using glLight, unless the modelview matrix was identified at the time glLight was called.

The value of state.light[n].position you get in your vertex program is exactly what is described here. You can think of state.light[n].position as calling glGetLight in your vertex program. So it’s the value you pass to glLight transformed by the modelview matrix that was set when glLight was called! So state.light[n].position is indeed a direction vector for a directional light when w = 0. If w = 1 it is a position.

It’s supposed to be in eye space, but there was a bug that I fixed…

[For the record, I’m going to be out of town and partially out of contact for the next week.]

  • Matt