ARB_fragment_program specification question

When ARB_fragment_program says that state.light.position is “the light position,” does that mean the light position verbatim as specified by the user with glLightfv(), or does it mean the “common” meaning of the light position, as transformed by changes in modelview matrix since the specification?

I’m seeing results that seem to indicate the former, but it seems that the latter would be much more immediately useful.

The user’s original vector is actually thrown away – nowhere in the GL state table is there an entry for it.

I don’t know what you are referring to by “as transformed by changes in the modelview matrix since the specification”. Light positions and directions are transformed only once, by the modelview matrix, at specification time. If the modelview matrix changes, light positions (in eye space, which is what matters) remain unchanged.

Conceptually, changing the modelview matrix does change lights’ positions in object space, but that’s it.

Certain NVIDIA drivers have had bugs wherein state tracking tracked the original light position from the user. I believe all such bugs are fixed, and that the original light position is really thrown away now.

  • Matt

hm… more and more working with that stuff i started to like the idea of having the modelview split into model and view… somehow it would feel much more clean to work with it…

possibly combining viewprojection, never seen much use for splitting them (as both are for the camera somehow)…

this question is exactly one of the reasons i don’t like the way gl splitted it…

glMatrixMode(GL_CAMERA);
glLoadIdentity();
gluPerspective(…);
gluLookAt(…);
glMatrixMode(GL_MODEL);
forEach(Model model in World) {
glLoadMatrixv(model.matrix);
model.draw();
}

and every light would be specified by default in world space, etc…

hm… how does dx handle it? only one matrix there at all i think

The GL model works fine, I find. “World space” is a valuable concept, but it doesn’t need to be enshrined in the API. (The API requires the projection matrix, however. You simply cannot merge the projection and modelview matrices without breaking the lighting model, clip planes, etc.)

If you want to specify your lights in world space, which is what makes sense most of the time, then you would first load your world->eye matrix into the modelview (essentially, your LookAt). Then, you can specify all your lights. For each object in the scene, you call PushMatrix, do your translate/rotate to locate the object in world space, draw the object, PopMatrix.

The GL model, however, also makes it easy to specify other types of light sources, like headlights. It would certainly be inconvenient to require that all light sources be placed in world space.

  • Matt

Originally posted by mcraighead:
The GL model works fine, I find. “World space” is a valuable concept, but it doesn’t need to be enshrined in the API. (The API requires the projection matrix, however. You simply cannot merge the projection and modelview matrices without breaking the lighting model, clip planes, etc.)

i think its pretty stupid the api requires the projection matrix. i don’t see much use for it. lighting does not need it for sure, and clipplanes don’t work correctly on most implementations anyways (according to the amount of posts i’ve seen ) and should be implemented instead with a DP4 in the ARB_fp. there you can do it (again) in the space you want. same for lighting.
yes you can always work around to use it. still i think gl proposed 3 matrices, and merged 2 of them. sometimes it would be more nice if they would not have been merged.


If you want to specify your lights in world space, which is what makes sense most of the time, then you would first load your world->eye matrix into the modelview (essentially, your LookAt). Then, you can specify all your lights. For each object in the scene, you call PushMatrix, do your translate/rotate to locate the object in world space, draw the object, PopMatrix.

and voilà, my code is filled with push and pop the whole time, showing that i in fact manually “emulate” two matrices… one always stays the same, the VIEW matrix namely…


The GL model, however, also makes it easy to specify other types of light sources, like headlights. It would certainly be inconvenient to require that all light sources be placed in world space.

no point why my ones would be required to be in world space. they are defined in their own object space (wich is often just the identity matrix, means they are defined in world space…)

glMatrixMode(GL_MODEL);
glLoadMatrixf(someMatrixOfAModelWithAHeadLight);
glLightv(…);
glDraw(…);

i just think gl is here inconsistent in merging two, not merging all 3, but proposing all 3, not making 2 of them availible…

we yet have MODELVIEWPROJECTION in most shaders, because its useful to have them in one. it would be useful to have them fully split as well.

i never said its needed => matt would never accept it. what is not needed does not need to be added/changed. never make the live more easy to the developers if they can work it out the hard way. i remember a similar statement from you when we discussed why nvidia creates such ugly to use extensions sometimes… its our job to make nice workarounds around it, not yours to make gl nice…

so i continue to push and pop around…

Well, the problems I was having went away when I changed from using state.light[0].position and specifying the light with the modelview set to identity, to program.env[0] and specified what I wanted myself as an eye space vector.

Now, Matt, you don’t need to worry about whether this is a bug of yours, 'cause it’s using a driver for some other hardware :slight_smile:

Speaking of which: fragment.position is supposed to be in WINDOW space, right? xy is supposed to always be the same value for the same window pixel, according to how I read the spec.

That’s not what I’m getting. I’m getting something that is mostly object aligned. Unless I’m having a bug in my shader. Here it is, for everyone’s amusement. The intended output is to get a checkerboard pattern in window space:

static char const * errorFragmentProgramText =
"!!ARBfp1.0
\


PARAM colorb = { 1.0, 1.0, 0.0, 1 };

PARAM colora = { 0.2, 0.6, 0.6, 1 };

PARAM consts = { 2, 0.125, 0.5, 0 };
\


OUTPUT oCol = result.color;
\


TEMP tpos;
\

\

scale by 1/8; wrap


MUL tpos.xy, fragment.position, consts.yyww;

FRC tpos.xy, tpos;
\

\

offset to center around 0


SUB tpos.xy, tpos, consts.zzzz;
\

\

get halves or nothing


CMP tpos.xy, tpos, consts.zzzz, consts.wwww;
\

\

add both into result and trim off wholes


ADD tpos.x, tpos.x, tpos.y;

FRC tpos.x, tpos.x;
\

\

scale by 2 and lerp to choose color


MUL tpos.x, tpos.x, consts.x;

LRP tpos, tpos.xxxx, colora, colorb;

MOV oCol, tpos;
\


END

";

(The “scale by 1/8” really ought to be “scale by 8” according to my understanding, too)

[This message has been edited by jwatte (edited 12-22-2002).]

fragment.position should be window-aligned from the bottom left of the window, as I understand it. In particular, you should also expect that its fractional part should be 0.5, since it is the position of the center of the pixel.

  • Matt

Matt,

Yes, that’s fine, that’s what I think the spec is saying. Unfortunately, that’s not what the implementation I’m working with seems to give me. I guess I’d file a bug report, except it doesn’t really matter all that much to me so I’m sure someone else will :slight_smile: