Войти
ПрограммированиеФорумГрафика

Не float атрибуты и точность операций

#0
11:11, 29 авг 2015

Недавно столкнулся с проблемой точности представления чисел с плавающей точкой при рендеринге тайловой сетки:
1. На вход поступают значения -1..1, двойной точности. Максимальная используемая точность - 2^26
2. Они как float передаются на рендер. float нормально может хранить только 2^23
3. Множатся на одну матрицу, в которой зашит и scale и translate и projection.
4. На выходе - очень большие ошибки, пиксели плавают по +-4 во все стороны :(

Не хватает точности float ни для передачи координат тайлов, ни для передачи матрицы - числа "округляются" где-то далеко, но важно, после запятой.

Идея номер 1 - передавать координаты тайлов не через float, а через uint - получаем гарантированную точность 2^32, маппинг в "старые" координаты как 1/N
Идея номер 2 - отказаться от матриц, передавать трансформацию исходными параметрами - viewport, zoom, center

Получаем координату тайла. Делим на zoomfactor, потом уже этим значением делим единицу - сразу нельзя, так как потеряем и так не гарантированную точность.

Что смущает:
1. Насколько я знаю - что либо кроме float может приводить к падению производительности в разы. Специфично для конкретного девайса, или драйвера - но опасность есть. Или с этим уже нормально?
2. Отказ от нормальных матриц убирает многие свистелки и перделки :(

Альтернативное решение - разбитие исходной карты на N сегментов таким образом, чтобы в каждом из них точности представления float хватало для точной адресации тайлов. Но это уже немного сложнее реализовывать.

Что может посоветовать %username%, особенно если работать должно и на девайсах с точностью mediump?

#1
11:20, 29 авг 2015

Чет подозрительно. Что рисуешь то хоть?

#2
11:25, 29 авг 2015

Ландшафт, большой, тайлами. Стандартные источники тайлов отдают их до 18 зума + 256 пикселей размер самого тайла.
Итого точность позиционирования 2^26 (18+8).

#3
12:17, 29 авг 2015

Проблема известная, начинают прыгать плоскости треугольников. Решение, нужно строить вершины объектов, и его положение,  относительно камеры.
То есть на рендер ты посылаешь не вершины или положение относительно мировых координат (достаточно посчитать положения объекта/сегмента относительно камеры), а вычитаешь из них положение камеры - камера автоматом становится в нулевых координатах.
Но это половина решения его хватить для того чтобы вершины посчитать используя double и спокойно преобразовать во float, для больших масштабов тебе придется перестраивать мировую систему координат.
С увеличением масштабов начнет неправильно позиционироваться сама камера, то есть double будет не достаточно, это тоже решаемо в иерархической системе координат. Мировая система координат делится на сегменты, имеющие свою локальную систему отсчета, и камера перемещается между этими сегментами.

#4
12:25, 29 авг 2015

Kashey
> Ландшафт, большой, тайлами
Тайлами? То есть, двухмерный, вид сверху?

#5
15:13, 29 авг 2015

Именно так.

#6
15:16, 29 авг 2015

Kashey
Считай координаты ландшафта целочисленно, а кусок, на который смотришь, перегоняй во float. Например, с нулем в центре камеры, да. Ну или еще как-то еще, чтобы по-реже перегонять.

#7
17:01, 29 авг 2015

Kashey
> Что может посоветовать %username%, особенно если работать должно и на девайсах
> с точностью mediump?
Это что за девайсы? По-моему в вершинных шейдерах везде есть highp. Его только во фрагментных шейдерах может не быть.

#8
17:21, 29 авг 2015

-Eugene-
Да хотелось бы избежать сей практики.
gammaker
Яж не настоящий сварщик. Но говорят, старые дроиды....

ПрограммированиеФорумГрафика

Тема в архиве.