HowTo:Fix artifacts

From POV-Wiki
Jump to navigation Jump to search

On occasion, some objects in your scene may have speckles or what looks like random noise on the surface. Below are a few possible causes:

Coincident Surfaces

Main article: Documentation:Tutorial Section 2.1#Co-incident Surfaces

Two or more surfaces occupy the same plane. The choice of which surface gets rendered varies from pixel to pixel according to the whim of POV-Ray. Translating one surface by 0.0001 out of the plane will usually fix this. This is probably the most common cause of 1px speckles on specific objects in a scene.

If you are trying to model a single object with both an inside and outside texture, you might try using the interior_texture keyword.

Radiosity

In scenes using radiosity, if the artifacts show up only when radiosity is turned on, then they are caused by radiosity sampling errors. If you haven't already done so, check the Official Documentation on Radiosity or the HowTo: tutorial on radiosity.

Transparent and Reflective Surfaces

Scenes that many reflective/transparent surfaces may run afoul of the default max_trace_level setting. Check the messages from the render, as POV-ray will tell you if the max_trace_level was reached during a render. If it was reached, raise the max_trace_level to a higher value.

Other Causes

You've rendered a scene using certain textures with anti-aliasing turned off. The difference caused by the use of anti-aliasing can be startling, especially with a texture which is supposed to have weird speckles! ;-) Note that the appearance of speckles on a surface is not only controlled by the pigment statement, but can be the result of a small, bumpy normal, or the use of crand in the finish statement.

Floating-point expressions

You've created an expression where some fractional or decimal values are operated upon to create an integer, but the expression doesn't evaluate to the correct amount. This problem is related to the one of co-incident surfaces, in that floating-point values are cut-off at a level that is less precise than the one you are checking for.

The underlying problem is the same as if you'd try to compute 1/3 + 1/3 + 1/3 + ... using decimal numbers with a certain limit in precision; as you can't exactly represent 1/3 this way, you'd get e.g.:

  0.33 + 0.33 = 0.66
  0.66 + 0.33 = 0.99
  0.99 + 0.33 = 1.32
  ...

In practice, if you have a fixed value to add, you can usually "re-normalize" the whole problem to use integers for your loop variable; e.g. instead of:

  #local Foo = 0.0;
  #while (Foo <= 1.0)
    ...
    #local Foo = Foo + MySmallValue
  #end

you can use:

  #local Bar = 0.0;
  #while (Bar * MySmallValue <= 1.0)
    #local Foo = Bar * MySmallValue;
    ...
    #local Bar = Bar + 1.0;
  #end

Somewhat more generally, any integer divided by any power of 2 is safe to add (unless it's extremely small compared to the "target value").