1.4.9.2 What causes the problem?
The problem is caused by the rendering algorithm used in POVRay. The following text is quite technical, so if you
just want to read about possible solutions to this problem, you can skip to the next subsection.
The problem is that the rendering engine assumes that objects return the true normal vector for the given
point in their surface. For an object to render correctly, it must give the exact normal vector (ie. a vector
which is exactly perpendicular to the surface at that point).
Smooth meshes and heightfields do not do this. They return normal vectors which are not perpendicular to the actual
surface. This causes errors in the rendering.
What happens is that when the rendering engine shoots a ray and it hits the surface of an object, the engine asks
the object "what is the normal vector at this point in your surface?". Now, if the angle between the
returned normal vector and the ray vector is less than 90 degrees (that is, the normal vector points away from the
point of view of the starting point of the ray), then the engine reverses the returned normal vector. This is
essential for the lighting to work properly (if the normal is not reversed in this case, you would get all kind of
errors in lighting, ie. surfaces which are illuminated from behind when they should not, or surface which are not
illuminated even though they are facing a light source).
This assumes that the normal vector returned by the object is a true normal vector, and it works perfectly
when this is so.
However, if the object returns an erroneous normal vector, ie. a vector which is not perpendicular to the surface,
rendering errors can occur.
Smooth triangles and heightfields do this, and the price to pay are the artifacts in the lighting in certain
situations.
The artifact is produced when the true normal vector would have an angle larger than 90 degrees with the ray, but
the the actual vector returned by the object has an angle smaller than 90 degrees with the ray. In this case the
rendering engine reverses the normal vector even though it should not. This is because it assumes that it is the true
normal vector when in fact it is not.
This problem could be solved by making the decision of inverting the returned normal vector according to the true
normal vector of the surface instead of the returned vector. However, due to the internal implementation of the
rendering engine in the current POVRay 3.5, doing this is not trivial. It may be fixed in POVRay 4.0, where the
rendering engine will be written again and this kind of things can be taken into account from the very beginning.
