### 9.9.2 What causes the problem?

The problem is caused by the rendering algorithm used in POV-Ray. 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 don't 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's 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 shouldn't, 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 shouldn't. This is because it assumes that it's the true normal vector when in fact it isn't.

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 POV-Ray 3.5, doing this is not trivial. It may be fixed in POV-Ray 4.0, where the rendering engine will be written again and this kind of things can be taken into account from the very beginning.