OpenGL Lighting 13. OpenGL Lighting • Overview of Lighting in OpenGL In order for lighting to have an effect in OpenGL, two things are required: A light An object to be lit Lights can be set to any color, and can have a wide variety of parameters which determine where they are located, in what direction they shine, and how they interact with objects in the world. Objects have a variety of parameters which determine how they reflect the light which hits them. The color(s) of an object is determined by the combining the parameters of the light(s) in the world with the object’s parameters. E.R. Bachmann & P.L. McDowell MV 4202 Page 1 of 32
32
Embed
13. OpenGL Lighting - MOVES Institutemovesinstitute.org/~mcdowell/mv4202/notes/lect13.pdf · OpenGL Lighting • Components of Lighting in OpenGL o OpenGL approximates light and lighting
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
OpenGL Lighting
13. OpenGL Lighting • Overview of Lighting in OpenGL
In order for lighting to have an effect in OpenGL, two things are required:
A light
An object to be lit
Lights can be set to any color, and can have a wide variety of parameters which determine where they are located, in what direction they shine, and how they interact with objects in the world.
Objects have a variety of parameters which determine how they reflect the light which hits them.
The color(s) of an object is determined by the combining the parameters of the light(s) in the world with the object’s parameters.
The three types of lights used in OpenGL are defined as follows:
Ambient:
Bounced light which has been scattered so much that it is impossible to tell the direction to its source (disappears if the light is turned off)
Diffuse:
Directional light which is brighter on perpendicular surfaces. Its reflection is scattered evenly.
Specular:
Directional light which tends to reflect in a preferred direction (associated with shininess)
Each of these three components has an effect on the lighting of each object in the world – the actual light at a location is the sum of the three types of lights
Just as in space, light is not noticable until it hits an object, and then its effect depends upon the object
o OpenGL approximates light and lighting as if light could be broken into red, green and blue components
- Light sources are characterized by the amount of red, green, and blue they emit
o Each light emits one or more of the three separate
types of light:
- Ambient, diffuse and specular - Each of these types has a red, green, and blue
component
o In addition to the lights that can be placed in a scene, the entire scene can be lit by a global ambient light, which will affect the lighting of every object in the scene, regardless of location or position
o Each object is composed of a material which has four properties that determine how the lighting model treats the object:
- emissive, ambient, diffuse and specular • ambient, diffuse and specular interact with the
corresponding types of light and determine what percentage of the respective types of light are reflected
• emissive allows an object to be a certain color even if not illuminated by any lights in the world emissive is most often used to simulate lamps and other light sources in a scene
Diffuse reflection is most intense where the light direction is perpendicular to the object’s surface
It is affected by the angle of the incident light relative to the normal direction
Diffuse reflectance isn’t affected by the position of the viewpoint
The diffuse term takes into account the diffuse color of the light, whether the light falls directly on the vertex, and the diffuse color of the material
The diffuse term is given by
(max{L • n, 0}) * diffuselight * diffusematerial (13.3)
where
- L is a unit vector pointing from the vertex to the light position
- n is the unit normal vector at the vertex
The diffuse components of a material are set by calling glMaterial with GL_DIFFUSE as the pname argument
- The current color may only be applied in one mode at a time; i.e., it is not possible to set both the specular and either ambient or diffuse colors to the current color at the same time
♦ Enabling glColorMaterial
Before glColorMaterial can be used, it must be enabled with
glEnable( GL_COLOR_MATERIAL );
Example 13.19 GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; glEnable( GL_COLOR_MATERIAL ); glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); // Set the ambient and diffuse properties glColor3f( 0.2, 0.5, 0.8 ); // Set the specular color glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular ); glColor3f( 1.0, 1.0, 1.0 ); // Draw the object auxSolidSphere( 1.0 );
To create a light which moves with the viewpoint, set the light position and position it when there are no viewing transformations on the stack
- Only the Identity matrix should be on the modelview stack
- Both the light and the view point will be affected in the same way
- IOW, position the light after the modelview stack has been cleared to the identity matrix, but before any viewing or modeling transformation are completed!
• Shadows
OpenGL does not directly support shadows
“Fake shadows” can be created by projecting three dimensional objects onto a two dimensional plane
- Three points that lie in the plane onto which the shadow will be projected
- The position of the light source casting the shadow
- A pointer to the projection matrix which is being returned
Two utility functions reduceToUnit and calcNormal are also shown
♦ makeShadowMatrix // Creates a shadow projection matrix out of the plane equation // coefficients and the position of the light. The return value // is stored in destMat[][]
GLfloat planeCoeff[4]; GLfloat dot; // Find the plane equation coefficients. // Find the first three coefficients the same way we // find a normal. calcNormal( points, planeCoeff ); // Find the last coefficient by back substitutions planeCoeff[3] = - ((planeCoeff[0]*points[2][0]) +
(planeCoeff[1]*points[2][1]) + (planeCoeff[2]*points[2][2])); // Dot product of plane and light position dot = planeCoeff[0] * lightPos[0] + planeCoeff[1] * lightPos[1] +
static const int x = 0; static const int y = 1; static const int z = 2; // Calculate two vectors from the three points v1[x] = v[0][x] - v[1][x]; v1[y] = v[0][y] - v[1][y]; v1[z] = v[0][z] - v[1][z]; v2[x] = v[1][x] - v[2][x];
v2[y] = v[1][y] - v[2][y]; v2[z] = v[1][z] - v[2][z]; // Take the cross product of the two vectors to get // the normal vector which will be stored in out out[x] = v1[y]*v2[z] - v1[z]*v2[y]; out[y] = v1[z]*v2[x] - v1[x]*v2[z]; out[z] = v1[x]*v2[y] - v1[y]*v2[x]; // Normalize the vector (shorten length to one) ReduceToUnit(out);
} // end calNormal
♦ ReduceToUnit // Reduces a normal vector specified as a set of // three coordinates, to a unit normal vector of length one. void ReduceToUnit( float vector[3] ) {
float length; // Calculate the length of the vector length = (float)sqrt( (vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2]) ); // Keep the program from blowing up by providing an // acceptable value for vectors that may evaluate // close to zero. if ( length > 0.0f ) { vector[0] /= length; vector[1] /= length; vector[2] /= length; } // end if