Tutorial 7 – Lighting
So far we’ve been colouring all of our polygons using specific colour values. Now we’re going to move a step further and use lighting to colour our polygons and hopefully generate a more realistic image.
Before we get to putting the lights into our code, we should first cover some terms that relate to lighting and reflection. There are 3 of these terms which describe different types of light which we will use to colour in our polygons. They are as follows:
This describes light that has left its source and bounced off many surfaces before reaching the eye
As you can see in the above diagram, the eye receives roughly the same amount of light from all directions. This gives an even “ambient” lighting to all the walls.
Any viewers within the 180° of the reflected hemisphere will see roughly the same colour being reflected from the surface.
Specular light, like diffuse, is another effect that is a result of the light’s angle of incidence upon a surface. Unlike diffuse light however, specular is light that is reflected almost perfectly by the surface with no scattering whatsoever.
In the above diagram, the incident yellow ray is reflected perfectly by the smooth surface meaning that the red eye sees a bright reflection whereas the black eye will see almost no light being reflected. Specular light gives surfaces a smooth shiny appearance.
Here is an example of some of the effects that you can achieve by using ambient, diffuse and specular lighting in OpenGL:
In OpenGL you can define 2 types of light source. Below is a diagram showing these 2 types:
These 2 types can be used to achieve difference effects. Point lights emit light equally in all directions. You might use a point light source to simulate something like a lamp on a wall or a gun’s muzzle flash. Directional light simulates parallel light rays and will give an even light effect across a surface. You might use directional light to simulate distant lighting sources like the sun.
Now that we know how light is emitted from sources, we need to look at how it is reflected from surfaces. All objects in OpenGL are drawn as a series of polygons which in turn are constructed of vertices. For each of these vertices it is possible to calculate a normal. A normal is a vector that is perpendicular to the adjacent 2 edges of a vertex. i.e. it points in the direction that the polygon is facing.
Using the direction of the incoming light ray and the angle at which it strikes a polygon, OpenGL can calculate how bright a polygon should appear. With all this knowledge we can now move on to….
To turn lighting on in OpenGL is actually extremely simple. All you need is 2 lines:
This code turns on OpenGL’s lighting calculations and then turns on the first light source. You can use more sources by enabling GL_LIGHTn (where n is the index of the light you want to turn on), but note, turning on multiple light sources can drastically affect performance.
Below is a video of a rotating cube illuminated using the default settings for GL_LIGHT0 along with the source code required to generate this program.