Это артефакт потери точности Povray?
Я экспериментирую с процедурным рельефом местности целых планет. Это означает, что я склонен рендерить очень большие объекты с очень близкого расстояния, и в результате я иногда сталкиваюсь с проблемами потери точности.
Мой последний генератор ландшафта производит изображения, которые выглядят следующим образом. Как видите, между некоторыми полигонами есть линии.
Дело в том, что я достаточно уверен, что мой генератор рельефа выводит правильную сетку - ручное наблюдение показывает, что треугольники, кажется, разделяют вершины, и соотношение вершина: грань составляет около 2:1, что правильно. Поэтому я не понимаю, как многоугольники не могут точно сталкиваться друг с другом.
Похоже, это может быть еще одной проблемой потери точности? Камера находится примерно на 0,1 мировой единицы над поверхностью, что составляет около 1750 мировых единиц от начала координат. Это не кажется достаточно большим, чтобы быть проблемой с поплавками двойной точности Povray, но...
(Если кому-то хочется взглянуть на исходный код генератора ландшафта, который находится на C++, он находится здесь: https://code.google.com/p/flooded-moon/source/browse/terrainmaker/sphericalroam.h)
Обновление: вот лучшее изображение, демонстрирующее проблему.
Камера теперь на 0,002 мировых единиц над поверхностью. Поверхность составляет около 1750 мировых единиц от происхождения. Мой масштаб составляет 1 единицу мира на километр; это означает, что странные артефакты имеют порядок сантиметров или около 0,00001. Это разница около 10^8. Достаточно ли этого, чтобы ошибки округления были значительными?
1 ответ
Я попытался воспроизвести размеры вашего пейзажа с помощью приведенного ниже кода POVRay. Здесь я показываю элементы поверхности шириной 10 см (0,0001), которые имеют различную высоту z=(i+j)*0,000001 (т. Е. 1 мм на каждый шаг). Я бы ожидал, что 2D лестницы будут постепенно подниматься с удалением от начала координат (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
К моему удивлению, это происходит:
В регулярных интервалах в шаблоне есть большие шаги, которые нельзя объяснить простой математикой описания сцены. Когда я изменяю на Радиус =1,0; артефакты исчезли:
Таким образом, вывод (и ответ на ваш вопрос, а не на проблему в целом) должен быть следующим: Да, у POVRay есть некоторые проблемы при добавлении больших и малых чисел. Может быть, есть переключатель, указывающий POVRay использовать двойную точность. Я не знаю. Я думаю, что есть опытные пользователи POVRay, которые просто улыбаются, когда читают это.
Надеюсь, это поможет. Во всяком случае, я тоже кое-что узнал, ответив на ваш вопрос.
Ура, Маркус