OpenGL offers a large selection of lighting features. The penalties some features carry may vary depending on the hardware you're running on. Be prepared to experiment with the lighting configuration.
As a general rule, use the simplest possible lighting model: a single infinite light with an infinite viewer. For some local effects, try replacing local lights with infinite lights and a local viewer. Keep in mind, however, that not all rules listed here increase performance for all architectures.
Use the following settings for peak performance lighting:
In addition, follow these guidelines to achieve peak lighting performance:
There may be a sharp drop in lighting performance when adding lights.
Local lights are noticeably more expensive than infinite lights.
If local lights must be used, a positional light is less expensive than a spot light.
Changing material parameters can be expensive. If you need to change the material parameters many times per frame, consider rearranging the scene to minimize material changes. Also consider using glColorMaterial() if you need to change some material parameters often, rather than using glMaterial() to change parameters explicitly. Changing material parameters inside a glBegin()/glEnd() sequence can be more expensive than changing them outside.
The following code fragment illustrates how to change ambient and diffuse material parameters at every polygon or at every vertex:
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); /* Draw triangles: */ glBegin(GL_TRIANGLES); /* Set ambient and diffuse material parameters: */ glColor4f(red, green, blue, alpha); glVertex3fv(...);glVertex3fv(...);glVertex3fv(...); glColor4f(red, green, blue, alpha); glVertex3fv(...);glVertex3fv(...);glVertex3fv(...); ... glEnd();
Local viewing: Setting GL_LIGHT_MODEL_LOCAL_VIEWER to GL_TRUE with glLightModel(), while using infinite lights only, reduces performance by a small amount. However, each additional local light noticeably degrades the transform rate.
Two-sided lighting illuminates both sides of a polygon. This is much faster than the alternative of drawing polygons twice. However, using two-sided lighting can be significantly slower than one-sided lighting for a single rendering of an object.
If possible, provide unit-length normals and do not call glScale() to avoid the overhead of GL_NORMALIZE. On some OpenGL implementations it may be faster to simply rescale the normal, instead of renormalizing it, when the modelview matrix contains a uniform scale matrix. The normal rescaling functionality in OpenGL 1.2, or the EXT_rescale_normal extension for older OpenGL versions, can be used to improve the performance of this case. If it is supported, you can enable GL_RESCALE_NORMAL_EXT and the normal will be rescaled making re- normalization unnecessary.
Some portions of the lighting calculation may be approximated with a table, and changing the GL_SHININESS value may force those tables to be regenerated.