Vertex Transformation

From OpenGL Wiki
Revision as of 05:23, 26 July 2008 by V-man (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This page contains a small example that shows how a vertex is transformed.
This page will demonstrate:
object space ---> world space
world space ---> eye space
eye space ---> clip space
clip space ---> normalized device space
normalized device space ---> window space


Let's built a projection matrix.

 glLoadIdentity();
 glFrustum(-0.1, 0.1, -0.1, 1.0, 1.0, 1000.0);

The resulting matrix looks like this

 [1.81, 0.00, 0.81, 0.00]
 [0.00, 1.81, 0.81, 0.00]
 [0.00, 0.00, -1.00, -2.00]
 [0.00, 0.00, -1.00, 0.00]

Let's built a very simple modelview matrix

 glLoadIdentity();
 glTranslatef(1.0, 2.0, 3.0);

The resulting matrix looks like this

 [1.0, 0.00, 0.00, 1.00]
 [0.00, 1.0, 0.00, 2.00]
 [0.00, 0.00, 1.00, 3.00]
 [0.00, 0.00, 0.00, 1.00]

and of course, the viewport also matters

 glViewport(0, 0, 800, 600);

The vertex you give to GL is considered to be in object space.
Let's assume the values are [21.5, 58.6, -99.6, 1.0]
Notice that w=1.0
When you transform a vertex by the modelview, the vertex is considered to be in eye space.
Note: The modelview matrix is actually 2 matrices in 1. The world matrix which transforms from object space to world space and the view matrix which transforms from world to eye space.
The vertex becomes [22.5, 60.6, -96.6, 1.0]
When you transform a vertex by the projection matrix, you get [-38.12, 31.14, 94.79, 96.59]. This is called clip coordinate.
Then w inverse is computed : 1/96.59 = 0.0103520
Each component is multiplied by the 1/w, you get [-0.394692, 0.322417, 0.981277, 1.0] This is called normalized device coordinates.
Here, if z is from -1.0 to 1.0, then it is inside the znear and zfar clipping planes.
Now the final stage of the transformation pipeline:
The z is transformed to the 0.0 to 1.0 range. Anything outside this range gets clipped away. Notice that glDepthRange() has an effect here. By default, glDepthRange(0.0, 1.0)
The final operation looks like this

 windowCoordinate[0]=(viewport[2] * x +(viewport[0] + viewport[2])) * 0.5;
 windowCoordinate[1]=(viewport[3] * y +(viewport[1] + viewport[3])) * 0.5;
 windowCoordinate[2]=(1.0 + z)*0.5;   //Convert to 0.0 to 1.0 range. Anything outside that ranges gets clipped.

and the vertex will now be [242.123, 396.725, 0.990639]
W doesn't matter.