The Shadow Line Artifact

From POV-Wiki
Jump to: navigation, search

What is the problem?

People often find an annoying problem when applying normal modifier patterns to objects. It is said that one image tells more than a thousand words, and this saying also applies here. This image shows two cases where the problem appears:

Sometimes odd shadow lines appear on certain objects!

  • The object in the left of the image is just a regular POV-Ray sphere with a normal modifier made with the bump pattern.
  • The object in right of the image is a mesh of smooth triangles.

As you notice, there are two clear artifacts in the image. The sphere has a straight shadow line which seems unnatural and the mesh has a non-straight shadow line when it's supposed to have a straight one.

Although the artifacts look quite different in nature, they are, in fact caused by the exact same problem.

The image one would expect.

What one could expect would be something like this image (don't mind about the bright part under the triangle mesh; this is explained later).

What causes the problem?

Let's start with the sphere with the perturbed normal, since it's easier to explain.

This image shows graphically what happens.

The problem happens in the dark side of the object, that is, the side which doesn't see the light source.

Although the surface normal points away from the light source (ie. its angle is >90 degrees from the light source), the perturbed normal points towards it (ie. its angle is <90 degrees) and thus, according to the normal vector, the light source should illuminate the point in question.

However, when doing the shadow-ray test, POV-Ray sees that the test ray intersects with a surface (in this case the surface of the same sphere, but at the other side). Thus it decides that the surface in question is shadowing the current point and thus the light source does not illuminate it.

Shadow line test with modified normals

This is what causes the straight shadow exactly where the (non-perturbed) surface normal is exactly at 90 degrees from the light source.

The problem with the mesh of smooth triangles is a bit more difficult, although very similar (and caused by the exact same problem).

This image shows graphically what happens.

Although there's no explicit normal perturbation, the fact that the surface is a mesh of smooth triangles means that there's an implicit normal perturbation.

In order to get a smooth appearance, each vertex has a normal vector and the normal vector at any point in the surface of the triangle is calculated by interpolating the normal vectors of the vertices.

Here the problem happens when the shadow line should pass across a triangle and the unperturbed normal vector of that triangle points away from the light source. As seen in the figure, a triangle that is closer to the light source will shadow the point in the current triangle (it's not necessarily the adjacent triangle, but if the mesh is closed, some triangle will surely shadow the point in question).

Shadow test of a triangle mesh

This means that this unfortunate triangle will be completely shadowed, thus causing a triangular artifact in the shadow line of the mesh.

The shadow line corresponds to the non-smooth mesh.

The image on the left shows more clearly why the shadow line of the smooth triangle mesh is like it appeared in the first image of this page.

The object at the left is the same triangle mesh, but with flat triangles, and the object at the right is the same object as in the image at the beginning of this page.

Notice how the shadowed triangles of the flat mesh correspond exactly to the artifacts in the shadow line of the smooth mesh. The reason for this was explained in the figure above.

Can this problem be solved?

And how did I correct the problem in the second image at the beginning of this page?

Firstly, don't think that it is a bug in POV-Ray. It isn't a bug, but a real problem caused be the lighting model used in the renderer engine that is quite difficult to surpass. It's not a problem in POV-Ray in particular, but a problem in raytracing in general. Every raytracer will have this same problem when using perturbed surface normals (unless there's some fix coded into it).

Perturbed surface normals are used, in fact, to simulate the perturbation of the surface itself. When calculating the lighting of the object, the surface normal perturbation will give the impression that the surface itself is perturbed (eg. in the images at the beginning of this page the sphere looks like it has a bumpy surface).

In triangle meshes the normal interpolation is used to simulate curvature of the surface (a curvature which actually isn't there).

However, since the normal vector perturbation doesn't affect the surface itself in any way, this kind of artifact will be the price to pay (another one is that although the surface looks bumpy or smooth, its silhouette will still look straight or polygonized, but this usually is not such a big problem).

This is a real problem that happens even to the best. For example, check this IRTC winner image. Notice the straight shadow lines on the rocks (specially in the closest rock)?

However, there are certain things that can be done to alleviate the problem.

Possible solutions?

  • So what did I do to get the second image at the beginning of this page?

I just made the objects shadowless. This gets rid of the problem of the surface shadowing the wrong point.

This, of course, has severe problems. Since the object doesn't cast shadows anymore, it probably can't be used in any real scene (although making the rocks shadowless in the IRTC winning image mentioned above would have perhaps helped the image a lot without making it too unrealistic).

With smooth triangle meshes it also introduces another artifact, which can be seen in the second image at the beginning of the page. This artifact happens because of normal inversion problems: it is usually hidden due to self-shadowing, but making the mesh shadowless makes also this problem appear.

  • Perhaps a future version of POV-Ray or one of its patches may introduce a way to stop self-shadowing (while still casting shadows on other objects).

This would alleviate the problem of the completely shadowless object since this object could be used in real scenes and they will cast shadows on other objects and they will not have the shadow line artifact.

However, this solution applies only to a few range of objects (mainly convex objects). Objects where self-shadowing is essential (imagine a coffee cup, for example) will still have problems.

  • I have proposed this sophisticated algorithm to get rid of the problem:

When doing shadow ray tests, do the following:

  1. Make the regular shadow ray test, which gets all the intersections of the ray with all the surfaces that are between the current point and the light source.
  2. Look if in the current point the unperturbed normal vector points away from the light source and the perturbed normal vector points towards the light source.
  3. If so, check if the closest intersection point of the shadow ray belongs to the current object.
  4. If so, remove that intersection point from the list.

If we want to be more sure, we could also check if we are hitting the inside of the surface at this closest intersection point and only then remove it. This might be necessary for non-closed surfaces.

This algorithm will eliminate the shadowline artifact without eliminating shadowing and self-shadowing of the object.

It has its defects, though:

  1. For example, if the camera is inside the object in question (and all the light sources are outside), we would expect to get a completely shadowed view of the surface. However, if the surface has perturbed normal, we will see some illuminated parts of the surface. However, I think that this problem is quite irrelevant in the vast majority of scenes (and it should be possible to turn the fix off anyways).
  2. It has several problems which can happen with non-convex objects (thanks to Ron Parker to pointing this out). The object can shadow itself with more than one surface. If it shadows itself from the outside (eg. a coffee cup), there's no problem, but if it shadows itself from the inside (eg. a coffee cup upside down) this shadow will be seen in an unrealistic way in the outermost surface of the object. There might not be any easy way to detect, which one is the case.
  3. Another problem similar to the above is that if there's another object inside this object we are calculating, that another object will itself also cast a shadow on the surface (this might be possible to fix by ignoring all the objects inside the current object; this is possible to do in a rather simple way; however, it's doesn't work in all cases).
  4. We still get the same artifact in triangle meshes as is shown in the second image at the beginning of the page. However, I'm sure that this problem could be fixed as well (although I may be wrong, of course).

End of Topic: Back to the Table of Contents

Personal tools
Other Pages