Depth Fighting

Depth values have limited resolution

i.e. the numbers are not infinitely precise

Rounding errors occur when polygons are filled

Polygon overlap can cause "depth-fighting"






Perspective Projection


Splinter Cell (Ubisoft)

Perspective-related depht cues are created by a perspective projection transformation

Perspective + movement yields motion parallax






Orthographic Projection

Orthographic projection : projects rectilinear box onto display
Objects will not appear to change size with distance






Perspective Projection

Perspective projection : projects frustum (truncated pyramid) onto disp lay
Near objects appear larger, distant objects appear smaller






Perspective Projection

GL's perspective projection is, conceptually, a pin-hole camera, located at origin, looking down -Z axis


Camera has a field-of-view - angle representing (horizontal) extent of region viewed

Small angle = narrow field-of-view = telephoto lens
Large angle = wide field-of-view = wide-angle lens






OpenGL Perspective

    gluPerspective( fovy, aspect, zNear, zFar )

fovy = field of view, in Y direction, in degrees

aspect = aspect ratio (X:Y) of window

zNear = distance to near clipping plane

zFar = distance to far clipping plane

The "eye-point" of the perspective projection is at (0,0,0)


Example:

    gluPerspective(45, 1.333, 0.1, 100)





Camera Movement

The OpenGL camera is always positioned at the origin, looking down the -Z axis.

The camera itself never moves.



Looking at the final image produced, moving a camera is equivalent to moving the world in the opposite direction.

e.g. moving everything to the right is will produce the same image as moving the camera to the left.






Camera Movement

To give the effect of moving the perspective viewpoint in OpenGL, use a transformation at the beginning of the frame, which affects all objects.

For example, to move the camera 10 units from the origin in the +Z direction, translate the world by -10 in Z:

def draw():
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(fovy, 1, 0.1, 100)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glTranslatef(0, 0, -10)

    drawObjects()





Camera Movement

For general camera movement:

def draw():
    global cameraPos
    global cameraHeading

    glLoadIdentity()
    glRotatef(-cameraHeading, 0, 1, 0)
    glTranslatef(-cameraPos[0], -cameraPos[1],
                 -cameraPos[2])

    drawObjects()





Inverting a Transformation

Inverse of glTranslatef(x, y, z) is glTranslatef(-x, -y, -z)

Inverse of glRotatef(angle, x, y, z) is glRotatef(-angle, x, y, z)

Inverse of glScalef(x, y, z) is glScalef(1.0/x, 1.0/y, 1.0/z)


Inverse of a series of transformations is the inverses of the individual transformations, in reverse order.






gluLookAt

Alternative method of camera control
gluLookAt computes and applies an appropriate translation & rotation


    gluLookAt(cameraX, cameraY, cameraZ,
              lookX, lookY, lookZ,
              upX, upY, upZ)

cameraX, cameraY, cameraZ is camera location - point to look from

lookX, lookY, lookZ is point to look at

upX, upY, upZ is "up-direction" for the camera - affects camera roll






Vectors

A vector is a direction and magnitude (length). Vectors are used to represent many different things - light source directions, surface orientations, relative distances between objects, etc.






Vectors

We normally describe a vector as a triplet of (X, Y, Z) values - (vx, vy, vz) represents a vector that points vx units in the direction of the X axis, vy units in the direction of the Y axis, and vz units in the direction of the Z axis.

e.g., (2, 0, 0) is a vector pointing in the direction of the X axis, 2 units long. (1, 1, 0) is a vector pointing at a 45 degree angle between the X and Y axes, 1.414 units long.

The magnitude of a vector (x,y,z) is its Euclidean length - the square root of vx2 + vy2 + vz2.






Vector Addition

Two vectors can be combined by adding their corresponding components together.
i.e. (vx, vy, vz) + (wx, wy, wz) is (vx+wx, vy+wy, vz+wz ).

Or, written more expansively:

  | vx |     | wx |     | vx + wx |
  | vy |  +  | wy |  =  | vy + wy |  
  | vz |     | wz |     | vz + wz |

The result is a vector that is equivalent to sticking the vector W onto the end of vector V, and creating a new vector from the beginning of V to the end of W.






Vector Addition






Vector/Scalar Multiplication

A vector can be multiplied by a single number (a "scalar") to change its length without changing its direction.

        | vx |     | s * vx |
  s  *  | vy |  =  | s * vy |
        | vz |     | s * vz |





Dot Product

The dot product of two vectors is an operation defined as:

  | x0 |   | x1 |
  | y0 | * | y1 |  =  x0*x1 + y0*y1 + z0*z1
  | z0 |   | z1 |  
The result is a single number, which is equal to the product of the lengths of the two vectors and the cosine of the angle between them.

It can tell us how much two vectors point in the same direction - it is maximum when they point in exactly the same direction, and it's 0 when they're at right angles.






Cross Product

The cross product is a function of two vectors that will produce a new vector perpendicular to both. The length of the cross product is equal to the area of the parallelogram formed by the two vectors.

The formula for the cross product of two vectors A & B is:

  [ ( Ay Bz - Az By ),   ( Az Bx - Ax Bz ),   ( Ax By - Ay Bx ) ]






Cross Product

The Python equivalent is:

def crossProduct(A,B):
    return [ A[1] * B[2] - A[2] * B[1],
             A[2] * B[0] - A[0] * B[2],
             A[0] * B[1] - A[1] * B[0] ]

The direction of the cross product is determined by the right-hand rule applied from vector A to vector B (so if you multiply them in the reverse order, the result will point the opposite direction).






Motion With Vectors

A vector can be used to represent the motion of an object.

The vector indicates the object's velocity - the direction of the vector is the direction that the object is moving, the magnitude of the vector is the speed.

The vector corresponds to how the object will move in one unit of time.
e.g., a velocity vector of (2, 0, 0) indicates that the object is moving 2 meters/second along the X axis (assuming our units are meters and seconds). If it starts at (3, 1, 0), then after 1 second its position will be (5, 1, 0). After 2 seconds, its position will be (7, 1, 0).

[Note that the choice of units is arbitrary, and is up to you when writing your programs; all that matters is that you be consistent within a program, and not, for instance, try to combine meters per second with miles per hour.]






Motion With Vectors

In general, if an object starts at position P0, with velocity V, then after t time units, its position P(t) will be:

            P(t) = P0 + t * V





Programming With Vectors

Creating a vector class allows one to work with vectors more simply.

Vector operations just require a single statement, rather than a loop or separate statements for X, Y, & Z components.

    a = Vector((1, 2, 3))
    b = Vector((0, -1, 0))
    c = a + 2 * b
    d = a.dot(b)





dmsgl Utilities

dmsgl.py

Misc functions:

Classes:

Creative Commons License
This document is by Dave Pape, and is released under a Creative Commons License.