Lighting

Rendering by Twirk88





Lighting

Lighting provides very significant cues to the 3 dimensional shape of objects.



Lighting in computer graphics attempts to simulate the behavior of light in the real world.
Real-time lighting involves significant simplifications.






OpenGL Lighting

To make OpenGL use lighting calculations when drawing objects, enable GL_LIGHTING:

 
    glEnable(GL_LIGHTING)

You must also turn on at least one light source:

    glEnable(GL_LIGHT0)

Example: drawcow.py






Lighting


Rendering by Alexandra constantin



Simulated lighting involves three major components:











Light Sources

Light source attributes are set by glLight.

A light source has a position and a color.
The intensity of the light is simply the intensity of the color.

    glEnable(GL_LIGHT0)
    glLightfv(GL_LIGHT0, GL_POSITION, [0, 1, 0, 0])
    glLightfv(GL_LIGHT0, GL_DIFFUSE, [1, 1, 1, 1])





Light Source Position

Lights can be infinite (a.k.a. directional) or local

All rays from an infinite light source come in the same direction.
Rays from a local light source come from a particular point in space.

The 4th value in the light source's position controls this feature:
   0 = infinite light
   1 = local light

# Light comes from above 
    glLightfv(GL_LIGHT0, GL_POSITION, [0, 1, 0, 0])

# Light comes from point (0,1,0)
    glLightfv(GL_LIGHT1, GL_POSITION, [0, 1, 0, 1])





Light Source Position

A light source's position is affected by the current transformation.

Lights should be defined after the camera transformation, in order to define them in "world" coordinates.

They can also be moved with transformations, just like an object.

# Make local light come from position (5, 0, 7)
    glPushMatrix() 
    glTranslatef(5, 0, 7)
    glLightfv(GL_LIGHT0, GL_POSITION, [0, 0, 0, 1])
    glPopMatrix()





Multiple Lights

You can enable multiple simultaneous lights.
The lights are named GL_LIGHT0, GL_LIGHT1, ...
At least 8 light sources are allowed - more may be available.

    glEnable(GL_LIGHT1)
    glLightfv(GL_LIGHT1, GL_POSITION, [-1, 1, 2, 0])

More lights = more computations, and potentially slower rendering






Materials

Material properties define how a surface reflects light.
Basically, they represent the surface color.

When lighting is active, glColor is ignored; the material is used instead.


Material properties are set using glMaterial.

    blue = [0.1, 0.4, 1, 1]
    glMaterialfv(GL_FRONT, GL_DIFFUSE, blue)





Light Source Color

Light sources can have a color & intensity.
The default is full white.

    blue = [0.1, 0.4, 1, 1]
    glLightfv(GL_LIGHT0, GL_DIFFUSE, blue)

The color of a light defines how much red, green, and blue light is shining on an object.
The color of a material defines how much red, green, and blue light it reflects.

The final color we see is the combination of the two - corresponding components are multiplied together.






Diffuse / Specular / Ambient

The basic lighting effect is diffuse lighting.

The intensity of diffuse lighting depends on the orientation of the surface relative to the light source.
Diffuse light is reflected equally in all directions.

Specularity is light that is more-or-less directly reflected off the surface to the camera.
Its intensity depends on the orientation of the surface relative to camera, as well as to the light source.

Ambient light comes from no particular direction.
It reflects equally in all directions






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 intensity is computed from the dot product of the surface normal and the light direction.

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.


Illustration by Oleg Alexandrov





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()

Example: ring-normals.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).


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

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

The length of the cross product is equal to the area of the parallelogram formed by the two vectors.






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).






Specularity

Specularity produces shiny highlights on surfaces.

It involves 3 attributes: the specular color and the shininess of the material, and the specular color of the light source.

    glLightfv(GL_LIGHT0, GL_SPECULAR, [1, 1, 1, 1])

    glMaterialfv(GL_FRONT, GL_SPECULAR, [1, 1, 1, 1])
    glMaterialf(GL_FRONT, GL_SHININESS, 50)

A higher GL_SHININESS value produces smaller highlights.

To disable specularity, set the specular color to black ([0,0,0,0])


CC-BY-SA photo by Andrzej Barabasz





Ambience

Ambient light simulates indirect lighting.

It is basically a constant level of lighting that's added to a surface's color, regardless of orientation.

The ambient lighting effect is the product of the light source's ambient color and the material's ambient color.

glLightfv(GL_LIGHT0, GL_AMBIENT, [0.1, 0.1, 0.1, 1])

glMaterialfv(GL_FRONT, GL_AMBIENT, [1, 1, 1, 1])

There is also a global source of ambient light, controlled by glLightModel

glLightModelfv(GL_LIGHT_MODEL_AMBIENT,[.1, .1, .1, 1])





Advanced OpenGL Lighting

Additional lighting features in OpenGL are:






Shaders


Rendering by GDallimore

Shaders are pieces of custom code that execute on the GPU itself, allowing rendering techniques not part of basic OpenGL

Current graphics cards support:

OpenGL shaders are written in a C-like language called GLSL







Illustration by the Khronos Group






Illustration by the Khronos Group


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