Domanda

I'm experimenting with procedural terrain generation of entire planets. This means I tend to render very big objects from very close up, and as a result I occasionally run into precision loss issues.

My latest terrain generator is producing images that look as follows. As you can see, there are lines in between some of the polygons.

Thing is, I'm reasonably sure that my terrain generator is outputting a correct mesh --- hand observation shows that the triangles seem to be sharing vertices, and the vertex:face ratio is about 2:1, which is correct. So I don't see how the polygons cannot precisely butt up against each other.

Does this look like it could be another precision loss issue? The camera is about 0.1 world units above the surface, which is about 1750 world units from the origin. This doesn't seem large enough to be an issue with Povray's double precision floats, but...

(If anyone feels like looking at the source code to the terrain generator, which is in C++, it's here: https://code.google.com/p/flooded-moon/source/browse/terrainmaker/sphericalroam.h)

Problematic image

Update: Here's a better image exhibiting the problem.

The camera's now 0.002 world units above the surface. The surface is about 1750 world units from the origin. My scale is 1 world unit to a kilometre; this means that the weird artifacting is on the order of centimetres, or about 0.00001. This is a difference of about 10^8. Is that enough for rounding errors to be significant?

Another problematic image

È stato utile?

Soluzione

I tried to reproduce the dimensions of your scenery with the POVRay code below. Here, I show surface elements of 10 cm (0.0001) width that have a varying elevation of z=(i+j)*0.000001 (i.e. 1 mm for every step). I would expect 2D stairs that gradually rise with distance from the origin (0.0,0.0,1750.0).

/* 
  display a planet's surface with real dimensions
 */
#include "colors.inc"

// dimensions
#declare Radius = 1750.0;   // planet radius in km
#declare nEl    = 100;      // nEl x nEl will be produced
#declare sEl    = 0.0001;   // size of one surface element
//
#declare camX = 0.0;
#declare camY = 0.0;
#declare camZ = Radius + 0.003

camera {
location <camX,camY,camZ>
look_at  <camX+1,camY+1,camZ-1>
angle 50
sky <0,1,0>
up <0,9,0>
right <16,0,0>  // up,right -> 16:9 
}
light_source { <camX,camY,camZ>
              color White
              fade_distance 2.0
              fade_power 1
}
#macro SElement(Xoff,Yoff,Zoff) 
#local cbase=<0.9,0.1,0.1>; // base color
#local hcolr=rand(hh)*0.1;  // color variation
#local hcolg=rand(hh)*0.1;
#local hcolb=rand(hh)*0.1;
#local OneElement = box { <0,0,0>, <1,1,1> 
     texture {
        pigment { color cbase+<hcolr,hcolg,hcolb> }
     } 
}
object{ OneElement
      scale sEl
      translate <Xoff,Yoff,Zoff> }
#end // macro SElement

// create surface from surface elements of varying elevation Zoff 
#local i=0;
#local j=0;
#while (i<nEl)
  #while (j<nEl)
    #local Xoff = i*(sEl);
    #local Yoff = j*(sEl);
    #local Zoff = Radius + (i+j)*0.000001; 
    SElement(Xoff,Yoff,Zoff)
    #local j=j+1;
  #end
  #local j=0;
  #local i=i+1;
#end 

To my surprise, this happens: Scene with camera angle 50

In regular intervals, there are large steps in the pattern that cannot be explained by the simple math of the scene description. When I change to Radius=1.0; the artefacts have disappeared: Same scene with Radius=1.0

So the conclusion (and the answer to your question, not to the problem in general) must be: Yes, POVRay has some issue when adding large and small numbers. Maybe there is a switch telling POVRay to use double precision. I don't know. I guess, there are experienced POVRay users who just smile when they read this.

I hope this helps. Anyway, I also learned something by answering your question.

Cheers, Marcus

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top