2009-12-18 1 views
1

Каков наилучший механизм обработки крупномасштабных структур и сцен?Бесшовные переходы масштаба на больших расстояниях (3D-рендеринг)

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

ответ

3

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

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

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 миллиона световых лет.

EDIT: Чтобы использовать эту функцию для непрерывной геометрии, таких как рельеф местности и т.д., вы должны разделить местность на куски размера один квадратные километры, координаты вершин в куске местности должны быть в диапазоне [0, 1000].

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

+0

hmmm Я не уверен, как это могло бы обойти ошибку с плавающей точкой, так как в очень больших масштабах вы все равно будете умножать 1000 на очень большое число, и ваша справедливая замена одного установленного масштаба и всех его проблем для new one =/ –

+0

ах Теперь я вижу, что вы получаете, но он все еще оставляет проблему очень очень больших структур, например планеты/горы/луны –

+0

@Tom Вы не можете хранить планету как одну сетку, по моему отредактированному ответу –

1

Взятые из http://www.gamedev.net/reference/business/features/spotlightFB/

Q: Space. Оно большое. Это ДЕЙСТВИТЕЛЬНО большой. Это должно быть сложным для кода в таких огромных масштабах - как вы относитесь к такой вещи ? Используете ли вы какие-либо специальные данные структур или единиц измерения ? help?

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

0

Может быть стоит посмотреть в теч за Bing Maps Deep Zoom

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

+0

nifty, как это применимо к 3D-геометрии вне silverlight? –

Смежные вопросы