Advanced
This section presents the equations used by OpenGL to perform lighting calculations to determine colors when in RGBA mode. (See "The Mathematics of Color-index Mode Lighting” for corresponding calculations for color-index mode.) You don’t need to read this section if you’re willing to experiment to obtain the lighting conditions you want. Even after reading this section, you’ll probably have to experiment, but you’ll have a better idea of how the values of parameters affect a vertex’s color. Remember that if lighting is not enabled, the color of a vertex is simply the current color; if it is enabled, the lighting computations described here are carried out in eye coordinates.
In the following equations, mathematical operations are performed separately on the R, G, and B components. Thus, for example, when three terms are shown as added together, the R values, the G values, and the B values for each term are separately added to form the final RGB color (Rj + R2 + R^, Gi + G2 + Gj, B; + B2 + Β^). When three terms are multiplied, the calculation is (Rj R2R3′ g;g2g3/ b !B2B3). (Remember that the final A or alpha component at a vertex is equal to the material’s diffuse alpha value at that vertex.)
The color produced by lighting a vertex is computed as follows:
vertex color = |
the material emission at that vertex + the global ambient light scaled by the material’s ambient property at that vertex + the ambient, diffuse, and specular contributions from all the light sources, properly attenuated |
After lighting calculations are performed, the color values are clamped (in RGBA mode) to the range [0, 11.
Note that OpenGL lighting calculations don’t take into account the possibility of one object blocking light from another; as a result, shadows aren’t automatically created. Also keep in mind that with OpenGL, illuminated objects don’t radiate light onto other objects.
Material Emission
The material emission term is the simplest. It’s the RGB value assigned to the GL_EMISSION parameter.
Scaled Global Ambient Light
The second term is computed by multiplying the global ambient light (as defined by the GL_LIGHT_MODEL_AMBIENT parameter) by the material’s ambient property (GL_AMBIENT value as assigned with glMaterial*()):
Each of the R, G, and B values for these two parameters are multiplied separately to compute the final RGB value for this term: (RjR2, GjG2, BjB 2).
Contributions from Light Sources
Each light source may contribute to a vertex’s color, and these contributions are added together. The equation for computing each light source’s contribution is as follows:
Attenuation Factor
The attenuation factor was described in "Position and Attenuation”:
where
If the light is a directional one, the attenuation factor is 1.
Spotlight Effect
The spotlight effect evaluates to one of three possible values, depending on whether or not the light is actually a spotlight and whether the vertex lies inside or outside the cone of illumination produced by the spotlight:
• 1 if the light isn’t a spotlight (GL_SPOT_CUTOFF is 180.0).
• 0 if the light is a spotlight, but the vertex lies outside the cone of illumination produced by the spotlight.
is the unit vector that points from the spotlight (GL_POSITION) to the vertex.
is the spotlight’s direction (GL_SPOT_DIRECTION), assuming the light is a spotlight and the vertex lies inside the cone of illumination produced by the spotlight.
The dot product of the two vectors v and d varies as the cosine of the angle between them; hence, objects directly in line get maximum illumination, and objects off the axis have their illumination drop as the cosine of the angle.
To determine whether a particular vertex lies within the cone of illumination, OpenGL evaluates (max {v · d, 0}), where v and d are as defined in the preceding discussion. If this value is less than the cosine of the spotlight’s cutoff angle (GL_SPOT_CUTOFF), then the vertex lies outside the cone; otherwise, it’s inside the cone.
Ambient Term
The ambient term is simply the ambient color of the light scaled by the ambient material property:
Diffuse Term
The diffuse term needs to take into account whether or not light falls directly on the vertex, the diffuse color of the light, and the diffuse material property:
where
Specular Term
The specular term also depends on whether or not light falls directly on the vertex. If L · n is less than or equal to zero, there is no specular component at the vertex. (If it’s less than zero, the light is on the wrong side of the surface.) If there’s a specular component, it depends on the following:
• The unit normal vector at the vertex
• The sum of the two unit vectors that point between (1) the vertex and the light position (or light direction) and (2) the vertex and the viewpoint (assuming that GL_LIGHT_MODEL_LOCAL_VIEWER is true; if it’s not true, the vector (0, 0, 1) is used as the second vector in the sum). This vector sum is normalized (by dividing each component by the magnitude of the vector) to yield.
• The specular exponent (GL_SHININESS)
• The specular color of the light (GL_SPECULARiight)
• The specular property of the material (GL_SPECULARmateriai)
Using these definitions, here’s how OpenGL calculates the specular term:
However, if L · n = 0, the specular term is 0.
Putting It All Together
Using the definitions of terms described in the preceding paragraphs, the following represents the entire lighting calculation in RGBA mode:
Secondary Specular Color
If GL_SEPARATE_SPECULAR_COLOR is the current lighting model color control, then a primary and secondary color are produced for each vertex, which are computed as follows:
primary color = |
the material emission at that vertex + the global ambient light scaled by the material’s ambient property at that vertex + the ambient and diffuse contributions from all the light sources, properly attenuated |
secondary color = |
the specular contributions from all the light sources, properly attenuated |
The following two equations represent the lighting calculations for the primary and secondary colors:
During texture mapping, only the primary color is combined with the texture colors. After the texturing operation, the secondary color is added to the resulting combination of the primary and texture colors.