4.6. Debugging LightsSeveral things could cause lighting not to work properly, and there are numerous ways to identify the source of the problem. 4.6.1. Debugging a Blank WindowIf OpenGL appears to have rendered nothing, try the following:
4.6.2. NormalsWhen first learning to use OpenGL, many programmers fail to supply correct normals. This type of error causes odd shading artifacts on lit surfaces. As a good rule of thumb, supply a unit-length normal for every vertex. If the application is specifying unit-length normals, yet odd lighting artifacts persist, it's possible that scale transformations in the model-view matrix are distorting the normals. If necessary, enable GL_RESCALE_NORMAL or GL_NORMALIZE to resolve this issue. 4.6.3. Incorrect Face CullingIf your application enables GL_CULL_FACE but has the vertex winding order reversed, you might be looking at back faces instead of front faces. In addition to causing other visual artifacts, this situation might make the light appear to be on the wrong side of your geometry. Replace your call to enable face culling with a call to glDisable( GL_CULL_FACE ). If disabling face culling resolves your lighting issue, see "glFrontFace" in OpenGL® Reference Manual for information on how to configure face culling properly. 4.6.4. Debugging Position and DirectionIf your lights appear in the wrong position or shine from the wrong direction, check to make sure that you're specifying the GL_POSITION each frame with the correct model-view transformation. Specifying the GL_POSITION each frame is required for some light types, and if your light is a headlight or some other type of light that doesn't require a refresh of the GL_POSITION each frame, this is still good debugging technique. You can always optimize specifying the GL_POSITION later, after you've identified and addressed any issues related to light position. Be sure to specify the GL_POSITION before rendering geometry illuminated by that light. If you use positional lights, first try a directional light instead. This will help verify that you've specified the vertex normals correctly. 4.6.5. Debugging Light ColorsIf you're using colored lights and not getting the results you expect, initially use white lights to verify that you've specified the correct material colors. Remember, for example, that a pure-red object lit by a pure-blue light will appear black, because red objects reflect only red light and absorb blue light. 4.6.6. Per-Vertex Lighting ArtifactsThe fact that OpenGL calculates lighting at each vertex could create lighting artifacts on low-resolution geometry, as shown in Figure 4-3. Figure 4-3. The sphere on the left has insufficient resolution for OpenGL to render the specular highlight accurately. This is not an issue for the sphere on the right, due to its higher resolution. Light and material parameters are identical for both spheres.Low-resolution geometry lighting artifacts are especially apparent in specular highlights. Inadequate resolution, however, could also cause visible artifacts in diffuse lighting. These artifacts will appear in the presence of either directional or positional lights, but positional lights often cause them to be more acute. Low-resolution geometry that rotates or moves relative to a light source will often have an unstable specular highlight that appears to crawl or swim over the surface, or to fade in and out. Geometry must have sufficient vertices for per-vertex lighting and Gouraud shading to produce acceptable results. Increasing geometric resolution could adversely affect performance, however, so try to find a good balance between lighting effects and number of vertices. You might also try specifying a smaller GL_SHININESS specular exponent to create a larger specular highlight that affects more vertices. If neither of these methods produces acceptable results, consider other OpenGL features, such as cube maps or per-fragment lighting in a fragment shader. Chapter 6, "Texture Mapping," describes using cube maps to improve specular highlights. You can implement per-fragment lighting in OpenGL version 2.0 by using fragment shaders, but this is beyond the scope of this book. See OpenGL® Shading Language for more information. 4.6.7. Missing Specular HighlightsSpecular highlights might not appear for several reasons. Check to ensure that the incident light and viewing angles are correct. The specular highlight won't appear unless the viewing angle coincides with the reflection of the incident light. Incorrect surface normals could cause OpenGL to calculate the reflection vector incorrectly, so check that your application is sending correct unit-length normals. Check your setting for the specular material color and specular light color. Remember that only GL_LIGHT0 defaults to a full-intensity specular color; other lights default to zero intensity. Check your GL_SHININESS value. Large values may create specular highlights too small to appear on low-resolution geometry. Temporarily set a much lower value, such as 1.0. If the specular highlight appears, you'll need to increase the resolution of your geometry, as discussed earlier in this chapter, or set GL_SHININESS to a smaller value. If you're using texture mapping with GL_MODULATE texture environment mode, you'll need to use secondary color or multitexturing to add a specular highlight. See Chapter 6, "Texture Mapping," for more information. 4.6.8. Line and Point ColorsOpenGL is a state machine. When your application enables lighting, OpenGL lights all subsequent primitives, including lines and points. Although lit lines and points can create some interesting effects, often this isn't the desired result. Most applications need to disable lighting before submitting line and point primitives. This causes OpenGL to render the primitives with the current primary color, rather than modify the primary color with lighting results. |