logo back up home forward   further reading more topics »

3D Theory - OpenGL Rendering

Rendering Pipeline

Object coordinates

Points in 3D space are represented by 3 numbers represented by its position in the x, y and z planes.

Normalized coordinates - frustum projection

In order to represent this on a 2D screen we need to define a projection. A frustum projection shows an object, which is closer to the camera as larger than an object which is further away. To do this, the x and y coordinates are scaled by an amount invsely propotional to the position in the z dimention.

Screen coordinates - frustum projection

The viewport transformation scales and shifts the normalised coodinates to fit the size of the screen.


Pipeline

The rendering pipline takes the model data and renders it on the screen. This is done partly by software and partly by hardware, the boundry between these depends on what graphics card and operating system that you are using.

As shown in the diagrams above, in a frustum projection, the x and y coordinates are scaled by an amount invsely propotional to the position in the z dimention. A 3x3 matrix cannot represent such a transformation, so in the pipline an additional variable 'w' is added to each coordinate. This is a scaling value, used to scale the x,y and z values depending on the inverse of its distance from the camera.

To do this, the matricies are increased to 4x4 to include this scaling value.

Projection Matrix

fd=1/Math::Tan(fovY/2);
aspect = ((double)Width/(double)(Height-30));

example (width=258 height=440) Aspect=0.629268
FD/aspect=5.93077841512884
FD=3.73205080756888

projection->m00 = FD/aspect;
projection->m01 = 0;
projection->m02 = 0;
projection->m03 = 0;
projection->m10 = 0;
projection->m11 = FD;
projection->m12 = 0;
projection->m13 = 0;
projection->m20 = 0;
projection->m21 = 0;
projection->m22 = (zFar + zNear)/(zFar - zNear);
projection->m23 = -1;
projection->m30 = 0;
projection->m31 = 0;
projection->m32 = (2 * zFar * zNear)/(zFar - zNear);
projection->m33 = 0;

Inverse Projection Matrix

mi00 = - FD*m23*m32 / det = aspect/FD

in example above = 0.16861193084690149207499690607832
mi01 = 0
mi02 = 0
mi03 = 0
mi10 = 0
mi11 = - FD/aspect*m23*m32 /det = 1/FD

in example above = 0.26794919243112251215656695782073
mi12 = 0
mi13 = 0
mi20 = 0
mi21 = 0
mi22 = 0
mi23 = - FD/aspect*FD*m23/det = 1/m32 = (zNear-zFar)/(2 * zFar * zNear)

assuming zFar = -20 and zNear=-3 then m23 = 17/(2 * 20 * 3) =0.141666667
mi30 = 0
mi31 = 0
mi32 = m02*m11*m30 - m01*m12*m30 - m02*m10*m31 + m00*m12*m31 + m01*m10*m32 - m00*m11*m32;
= - m00*m11*m32;
= - FD/aspect*FD*m32/det
= 1/m23
= -1
mi33 = + FD/aspect*FD*m22/det = -m22/(m23 * m32) = m22/m32 = (zFar+zNear) / (2*zFar*zNear)

assuming zFar = -20 and zNear=-3 then m33 = -23 / (2*20*3) = -23/120 = 0.19166667


det= m03 * m12 * m21 * m30-m02 * m13 * m21 * m30-m03 * m11 * m22 * m30+m01 * m13 * m22 * m30+
m02 * m11 * m23 * m30-m01 * m12 * m23 * m30-m03 * m12 * m20 * m31+m02 * m13 * m20 * m31+
m03 * m10 * m22 * m31-m00 * m13 * m22 * m31-m02 * m10 * m23 * m31+m00 * m12 * m23 * m31+
m03 * m11 * m20 * m32-m01 * m13 * m20 * m32-m03 * m10 * m21 * m32+m00 * m13 * m21 * m32+
m01 * m10 * m23 * m32-m00 * m11 * m23 * m32-m02 * m11 * m20 * m33+m01 * m12 * m20 * m33+
m02 * m10 * m21 * m33-m00 * m12 * m21 * m33-m01 * m10 * m22 * m33+m00 * m11 * m22 * m33;
= -m00 * m11 * m23 * m32;
=FD/aspect * FD * m23 * m32

[0.168611930846902 0 0 0]
[0 0.267949192431123 0 0]
[0 0 0 0.141666666666667]
[0 0 -1 0.191666666666667]


Picking

How to do reverse process, select 3d object from 2d position on screen,

  1. generate the ray
  2. traverse the scenegraph to pick the nearest object along the scenegraph

how to pick the nearest object


metadata block
see also:

 

Correspondence about this page

Book Shop - Further reading.

Where I can, I have put links to Amazon for books that are relevant to the subject, click on the appropriate country flag to get more details of the book or to buy it from them.

cover cover

If you are doing a lot of OpenGL programming, and you can afford it. It really helps (in fact its almost essential) to have these 2 books at hand. The programming guide (red cover) explains the theory and the reference manual (blue cover) has complete definitions for all the API calls.

Commercial Software Shop

Where I can, I have put links to Amazon for commercial software, not directly related to this site, but related to the subject being discussed, click on the appropriate country flag to get more details of the software or to buy it from them.

 

cover Dark Basic Professional Edition - It is better to get this professional edition

cover This is a version of basic designed for building games, for example to rotate a cube you might do the following:
make object cube 1,100
for x=1 to 360
rotate object 1,x,x,0
next x

cover Game Programming with Darkbasic - book for above software

Can this page be improved?

Please send me any improvements to here. I would appreciate ideas to make the pages more useful including error correction, ideas for new pages, improvements to wording. It helps if you quote the full URL of the page.

 

progam

I am working on a project which uses these principles, if you would like to help me with this you are welcome to join in, here:

http://sourceforge.net/projects/mjbworld/

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2008 Martin John Baker - All rights reserved.