Skip to main content
gamedev.net
🔒 Locked

Shader Help

Started by Prozak May 5, 2004 at 1:55 AM 0 replies 300+ views
Original Post
Prozak
Prozak
Hi all, basicly, I want to have a situation where, in my shader, the light source and the model are in the same "space". My render calls are layed out as such: ========================================================== gluLookAt(); // Set Camera glLightfv(); // Set Light Position - (Q1) pushMatrix(); do_Rotation_Translation_of_Object(); - (Q2) Draw_Object(); popMatrix(); ========================================================== Q1: What space are we in, after gluLookAt? Eye-Space? Q2: And after these rotations/translations? So, where should i "harvest" the necessary matrices to pass onto my vertex shader, so that i can either "put" the light onto the same space as the objects, or "put" the obbjects in the same space as the light? Thanks for any pointers on this Salsa cooked it, your eyes eat it!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD][My DevDiary]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"our stupidity allways comes back to bite us in the ass... in a white-shark sort of way..." - Prozak
Lutz
Lutz
Hey!

There are 3 coordinate systems:
1) Object/World coords
2) Eye coordinates
3) Window coordinates, often called homogeneous clip space

All OpenGL transforms work with 2 matrices, the ModelView and the Projection matrix.

The ModelView matrix transforms 1) to 2).
The Projection matrix transforms 2) to 3).

The vertices of your model AND THE LIGHT POSITION are stored in object/world coordinates. Which term is more suitable depends on the way your ModelView matrix is set. In your case, after gluLookAt() (see below), one would rather call it world coords, after do_Rotation_Translation_of_Object() one would rather call it object coords (the do_Rotation_Translation_of_Object() routine concatenates the object-to-world transforms to the world-to-eye ModelView matrix, so that you get an object-to-eye ModelView matrix).

Eye coordinates are still 3D. You can imagine an object in eye coordinates as sitting somewhere behind your screen (but still 3D!).

The projection matrix makes window coordinates out of eye coordinates by projecting the 3D eye coords to (essentially) 2D window coords. (the 3rd dimension is used for clipping). X and Y window coordinates are both in the inverval [-1,1] and correspond directly to pixel position. They are mapped to pixel position by the viewport transform.

I''m not definitely sure about this, but I guess if you do gluLookAt , the ModelView matrix is loaded with a matrix transforming world coords in such a way that objects on the look-at-position will be transformed to the center of the screen. The projection matrix is loaded with the corresponding perspective projection.

Now back to your question:

Q1) The vector you pass to glLightfv is transformed by the ModelView matrix. The light position is in EYE SPACE afterwards. If you ask OpenGL for the light position in a vertex shader, you will get it in EYE SPACE. If on the other hand you pass the same light position as used in glLightfv() as a variable to the shader, you have to transform it by the ModelView matrix (the version of the ModelView matrix when you called glLightfv(), not the current one!)

Q2) The do_Rotation_Translation_of_Object() stuff modifies just the ModelView matrix. Every vertex passed to the GPU in Draw_Object() is transformed by this ModelView matrix. After the transform, the vertices are also in EYE COORDS.

So I would recommend this:
- Pass the ModelView matrix to the shader.
- Transform the vertices by this ModelView matrix
- Ask OpenGL for the position of your light.
- Now both points are in eye space.
- (Note: the vertex position you pass to the fragment program NOT ModelView * input vertex position, but ModelViewProj * input vertex position)

Hope this makes things clearer.

Lutz

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.