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.
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.
Changing material parameters can be expensive. If you need to change the material parameters many times per frame, consider rearranging the scene traversal 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.
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 is significantly slower than one-sided lighting for a single rendering of an object.
If possible, provide unit-length normals and don't 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 EXT_rescale_normal extension may be supported by these implementations to improve the performance of this case. If so, you can enable GL_RESCALE_NORMAL_EXT and the normal will be rescaled making re-normalization unnecessary.
Setting a new GL_SHININESS value requires significant computation each time.
Calling glMaterial() between glBegin()/glEnd() has a serious performance impact. While making such calls to change colors by changing material properties is possible, the performance penalty makes it unadvisable. Use glColorMaterial() instead.