Плавные переходы масштаба на большие расстояния (3D-рендеринг) - PullRequest
1 голос
/ 18 декабря 2009

Каков наилучший механизм для обработки крупномасштабных структур и сцен?

Примеры - континент с масштабными городами и географией, или планетарные переходы в стиле бесконечности во вселенной.

Ответы [ 3 ]

3 голосов
/ 18 декабря 2009

Самая большая проблема при работе с представлениями позиций с плавающей точкой в ​​крупном масштабе заключается в том, что вы быстро теряете точность по мере того, как все дальше и дальше отдаляетесь от начала координат.

Чтобы исправить это, вам нужно выразить все позиции относительно чего-то другого, кроме источника. Самый простой способ сделать это - разделить мир на сетку и сохранить позиции всех сущностей примерно так:

struct Position {
    int kilometers[3]; // x, y and z offset in kilometers
    float offset[3]; //x, y and z offset in meters
};

Положение камеры также сохраняется таким образом, и когда приходит время рендеринга, вы делаете что-то вроде этого:

void
getRelativePosition(float& x, float& y, float& z, const Position& origin, const Position& object) {
    x = (object.kilometers[0] - origin.kilometers[0]) * 1000.0f +
        (object.offset[0] - origin.offset[0]);
    //Ditto for y and z
}

//Somewhere later
float x, y, z;
getRelativePosition(x, y, z, camera.position(), object.position());
renderMesh(x, y, z, object.mesh());

(Для простоты я проигнорировал ориентацию камеры и объектов в этом примере, поскольку с этим нет особых проблем).

Если вы работаете с непрерывным миром в галактическом масштабе, вы можете заменить параметр kilometers на long long (64 бита), обеспечив эффективный диапазон 1,8 миллиона световых лет.

РЕДАКТИРОВАТЬ: Чтобы использовать это для непрерывной геометрии, такой как ландшафт и т. Д., Вы должны разделить ландшафт на куски размером один квадратный километр, координаты вершин на участке местности должны быть в диапазоне [0, 1000].

Также в приведенной выше функции getRelativePosition вы можете изменить ее, чтобы она возвращала bool и возвращала false, если разница в километрах больше некоторого порога (скажем, расстояния до вашей дальней плоскости отсечения).

1 голос
/ 18 декабря 2009

взято с http://www.gamedev.net/reference/business/features/spotlightFB/

Q: Space. Оно большое. Это действительно большой. Это должно быть утомительно, чтобы код в такой огромной весы - как вы идете о такой вещь? Используете ли вы какие-либо специальные данные структуры или единицы измерения для помочь?

A: Как вы можете себе представить, работа с один тип устройства не работает. я использовать иерархическую систему единиц. В Галактический уровень, световой год (LY) единицы используются. На звездной системе уровень, километр является базовой единицей, и координаты представлены двойная точность с плавающей точкой номера. Во время рендеринга вершины генерируется как поплавки одинарной точности, но переведено в пространство камеры минимизировать потерю точности из-за большие цифры.

0 голосов
/ 19 декабря 2009

Возможно стоит взглянуть на технологию, стоящую за Bing Maps Deep Zoom

Подобная технология используется Google Планета Земля, которая позволяет довольно плавно переходить от просмотра Планеты к просмотру улиц. Очевидно, что при увеличении и уменьшении происходит много изменений разрешения.

...