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:
- 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.
- 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).
- 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.
- 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.
- 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.
- 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.
- 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.
- If the shading is not perspective correct then as the polygon rotates
from face-on towards edge-on, you'll get more colour shifts.
- (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.
- 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.
- 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?