Smooth Shading 'Gotcha's in OpenGL

OpenGL supports smooth shading in which the colour or surface normal of each vertex of a polygon may be specified independantly and OpenGL will blend between them.

Unfortunately, there are a number of things that can go wrong (or which are wrong-by-design) that can cause smooth shaded polygons to look bad.

There was a long thread about this on the OpenGL-Gamedev list - here is my summary of the things that could potentially go wrong:

  1. Lighting only at vertices causes problems if your polygons are not tiny because OpenGL presumes rate of change of lighting across the polygon to be constant.

  2. Lighting only at vertices if lighting comes after clipping (which it shouldn't) would screw up because interpolating normals is not the same as interpolating light intensities. (We don't know for sure if anyone does this - but it might be a tempting optimisation).

  3. If colours are not a linear function of space (which they won't be with OpenGL lighting) then quads and polygons will shade differently depending on how OpenGL splits them into triangles.

  4. Even if OpenGL splits quads into triangles consistently when the quad is utterly on-screen, it might not do so when the quad is being clipped if triangulation happens after clipping.

  5. If the triangle is clipped then if the clipping is perspective correct (which it usually is) and the shading is not (and it often isn't) then triangles will change colour as they clip.

  6. Hypothetically (although we don't know of an implementation that does this) if the clipping *isn't* perspective correct but the shading *is* then you'd have the inverse problem to (4) and a very similar result.

  7. Even if you have only triangles at the outset, then a triangle that has one vertex off-screen is clipped to a quad which is then triangulated. If your implementation deliberately does non-perspective correct clipping in order to match non-perspective correct shading - THEN...(deep breath) that triangulation of the clipped quad will have colours are not a linear function of space. The result will therefore be different if GL suddenly chooses to split the resulting quad a different way.

  8. If the shading is not perspective correct then as the polygon rotates from face-on towards edge-on, you'll get more colour shifts.

  9. (and I saw this one not too long ago)...if this is a typical demo/test case with a white triangle on a black background - and if you have a cheap and nasty monitor (or *ESPECIALLY* a TV-video-output), then filling the screen with white pixels causes the CRT beam voltage to drop causing a general dimming of the scene.

  10. Since most boards don't have gamma-correction circuitry, and even those that do are often not set up appropriately, shading on a polygon will often be non-linear.

  11. It has also been speculated that under some extreme conditions, roundoff error during clipping could result in some rather nasty colour shifts.

What to do about them?

Many of these problems can be avoided by never using GL_QUADS, GL_QUADSTRIP or GL_POLYGON.

Others are utterly unavoidable.

Try not to lose any sleep over them - OK?