Homework 5

DUE: Tuesday, 27 October, in class

Create a 3D environment with intentionally mismatched depth cues.

Include multiple 3D objects. Have the objects move in 3 dimensions, or have the camera move, or both.

Use multiple depth cues, and make some of them conflict. The conflict should be clear, but perhaps not always immediately obvious.






OpenGL Lighting






Surface Orientation

To calculate how much light reflects off of a surface, OpenGL needs to know which direction the surface is facing.

The surface orientation combined with the direction of the light determines the intensity of the diffuse component of lighting.

The surface orientation, light direction, and direction to the viewer determines the specular component.






Normals

The orientation of a surface is defined by a normal - a vector perpendicular to the surface.

A normal should be a unit vector - its length should be 1.






OpenGL Normals

Normals in OpenGL are given with the glNormal function.

Lighting calculations use a normal at each vertex drawn;
you can provide a normal with each vertex, or fewer.

glBegin(GL_TRIANGLES)

glNormal3f(0, 1, 0)
glVertex3f(-1, 0, 0)

glNormal3f(0, 1, 0)
glVertex3f(1, 0, 0)

glNormal3f(0, 1, 0)
glVertex3f(0, 0, 2)

glEnd()

Examples: normal.py ring-normals.py cube.py






Computing Normal Vectors

Often you will have 3D polygonal data for an object, but need to generate normal vectors for it, in order to light it.

To compute normals from polygonal vertex data, use the cross product.

The cross product produces a new vector that is perpendicular to the two multiplied vectors. If the two vectors are edges of a polygon, then the cross product will give you a normal vector for the polygon (you will need to normalize its length to be 1.0, however).






Spotlights

Normally, local light sources shine equally in all directions.
Using spotlight options, you can have a light shine in a particular direction.

A spotlight's beam is a cone starting from the light position and pointing in the spotlight direction (GL_SPOT_DIRECTION).

The angle of the cone is defined by the GL_SPOT_CUTOFF value.

GL_SPOT_EXPONENT makes the brightness of the spotlight fall off toward the edges.


glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction)
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, angle)
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, exponent)





Spotlights

All lighting calculations are done only at the vertices.

Spotlights, like specular highlights, will not work well with large polygons.

The geometry must be finely tesselated for a good spotlight effect.






Attenuation

In the real world, the amount of illumination from a light source decreases the farther away you are from it.

By default, OpenGL lighting is the same, no matter how far you are from a light source.

Attenuation simulates the falloff of light with distance.






Attenuation

OpenGL attenuation uses a formula with 3 adjustable coefficients, so that you can vary light realistically, or semi-realistically:

                         1
brightness = -----------------------
              Kc + Kl * d + Kq * d^2

These coefficients are controlled by the following calls:

glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, Kc);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Kl);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Kq);





Attenuation

Some example results:

Kc, Kl, Kqd = 0d=0.5d=1d=10d=100
1, 0, 0 1 1 1 1 1
1, 0.1, 0 1 0.95 0.91 0.5 0.09
1, 0, 0.1 1 0.98 0.91 0.09 0.001
0.1, 0.1, 0 10 6.67 5 0.91 0.1





Two-Sided Lighting

Two-sided lighting affects how the backs of polygons are rendered.

It is enabled with glLightModel:

    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE)

A separate material can be specified for the backs of polygons:

    glMaterialfv(GL_BACK, GL_DIFFUSE, [1, 1, 1, 1])





Two-Sided Lighting

The front of a polygon is the side where the vertices appear in counter-clockwise order.

Front Back





Two-Sided Lighting

When two-sided lighting is enabled:

    if front side of polygon faces camera:
          use GL_FRONT material
          use normal as given

    else if back side faces camera:
          use GL_BACK material
          reverse normal

When two-sided lighting is not enabled, the back of a polygon is illuminated exactly the same as the front - both sides will show the same color.






Fog

Fog is a useful effect for realistic large-scale scenes.

It provides an additional depth cue for distant objects - aerial perspective.

It can also be used to hide the edges of a 3D world.






glFog

OpenGL fog mixes the color of a fragment with the color of the fog. The degree of mixing is a function of the distance from the camera to the fragment.

finalColor = (1-f) * polyColor + f * fogColor

Example:

    glEnable(GL_FOG)
    glFogi(GL_FOG_MODE, GL_LINEAR)
    glFogfv(GL_FOG_COLOR, [1, 1, 1, 1])
    glFogf(GL_FOG_START, 5.0)
    glFogf(GL_FOG_END, 40.0)





Fog Mode

There are three different fog modes:

glFogi(GL_FOG_MODE, GL_LINEAR)
Fog ranges from none at near distance (GL_FOG_NEAR) to full at far distance (GL_FOG_FAR)

glFogi(GL_FOG_MODE, GL_EXP)
glFogi(GL_FOG_MODE, GL_EXP2)
Fog density is an exponential function of the distance. The density is varied by the GL_FOG_DENSITY parameter.


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