Difference between revisions of "Vertex Transformation"

From OpenGL Wiki
Jump to: navigation, search
(Making correction and adding other examples)
m (minor)
Line 38: Line 38:
 
The vertex you give to GL is considered to be in object space.
 
The vertex you give to GL is considered to be in object space.
  
Let's assume the values are [1.5, 1.6, -99.6, 1.0] Notice that w=1.0
+
Let's assume the values are [1.5, 1.6, -99.6, 1.0] Notice that w=1.0. W is usually equal to 1.0 even if you don't submit it to GL. Anything that is a point will have W=1.0 such as point lights and the position of a spot light.
  
When you transform a vertex by the modelview, the vertex is considered to be in eye space.
+
When you transform a vertex by the modelview matrix, 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.
 
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.
Line 46: Line 46:
 
The vertex becomes [2.5, 3.6, -96.6, 1.0]
 
The vertex becomes [2.5, 3.6, -96.6, 1.0]
  
== Step 2 : Getting at clip coordinates ==
+
== Step 2 : Getting to clip coordinates ==
 
When you transform a vertex by the projection matrix, you get [83.58, 36.0, 94.7914, 96.6]. This is called clip coordinate.
 
When you transform a vertex by the projection matrix, you get [83.58, 36.0, 94.7914, 96.6]. This is called clip coordinate.
  
== Step 3 : Getting at normalized device coordinates ==
+
== Step 3 : Getting to normalized device coordinates ==
 
Then w inverse is computed : 1/96.6 = 0.0103520
 
Then w inverse is computed : 1/96.6 = 0.0103520
  
Line 56: Line 56:
 
Here, if z is from -1.0 to 1.0, then it is inside the znear and zfar clipping planes.
 
Here, if z is from -1.0 to 1.0, then it is inside the znear and zfar clipping planes.
  
== Step 4 : Getting at window space ==
+
== Step 4 : Getting to window space ==
 
Now the final stage of the transformation pipeline:
 
Now the final stage of the transformation pipeline:
  

Revision as of 00:14, 11 April 2011

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

So looking at the above, there are 5 steps. In GL, the modelview matrix is actually a 2 in 1 matrix. It is the camera matrix multiplied with the object's transform matrix. Therefore, there are actually 4 steps.

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, 10.0, 0.00, 0.00]
 [0.00, 0.00, -1.002, -2.002]
 [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);

Step 1 : Getting to eye coordinates

The vertex you give to GL is considered to be in object space.

Let's assume the values are [1.5, 1.6, -99.6, 1.0] Notice that w=1.0. W is usually equal to 1.0 even if you don't submit it to GL. Anything that is a point will have W=1.0 such as point lights and the position of a spot light.

When you transform a vertex by the modelview matrix, 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 [2.5, 3.6, -96.6, 1.0]

Step 2 : Getting to clip coordinates

When you transform a vertex by the projection matrix, you get [83.58, 36.0, 94.7914, 96.6]. This is called clip coordinate.

Step 3 : Getting to normalized device coordinates

Then w inverse is computed : 1/96.6 = 0.0103520

Each component is multiplied by the 1/w, you get [0.86522016, 0.372672, 0.9812785, 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.

Step 4 : Getting to window space

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] = (x * 0.5 + 0.5) * viewport[2] + viewport[0];
 windowCoordinate[1] = (y * 0.5 + 0.5) * viewport[3] + viewport[1];
 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 XYZ = [746.1, 411.8, 0.990639]

W doesn't matter.

More Examples

So in the example above, the z ended up being 0.990639. Since it is between 0.0 and 1.0, this vertex will not get clipped.

What if the vertex is [1.5, 1.6, 5.0, 1.0]?

eye space vertex would be [2.5, 3.6, 8.0, 1.0]

clip coordinates would be [-2.0, 36.0, -10.018, -8.0]

1/w is -0.125

normalized device coordinates would be [0.25, -4.5, 1.25225, 1.0]

window space would be XYZ = [500.0, -1050.0, 1.12613]. W doesn't matter.

Since y is below 0.0, this vertex would get clipped. Since z is above 1.0, this vertex would get clipped.

Another example :

What if the vertex is [1.5, 1.6, -1010.0, 1.0]? Notice that the z value is above the zfar value supplied to glFrustum (ignoring the negative sign).

eye space vertex would be [2.5, 3.6, -1007.0, 1.0]

clip coordinates would be [828.455, 36.0, 1007.01, 1007.00]

1/w is 0.000993

normalized device coordinates would be [0.822655815, 0.035748, 0.99996093, 1.0]

window space would be XYZ = [729.078, 310.725, 1.00001]. W doesn't matter.

The x and y value are fine but the z value is above 1.0, so this vertex would get clipped.