Марширующие кубики, воксели, нужно немного предложений - PullRequest
8 голосов
/ 04 января 2012

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

Я постараюсь кратко объяснить, как я строю свою местность, и, возможно, кто-то из вас даст мне совет, как улучшить или увеличить разрешение конечной местности.

1) Предварительный расчет треугольников MC.

Я запускаю простой цикл просмотра справочных таблиц MC для каждого случая (0-255) и вычисления треугольников. в ярости: [0,0,0] - [1,1,1]. Здесь нет проблем.

2) Рельеф

У меня есть класс местности, в котором хранятся мои воксели. В общем, это выглядит так:

int size = 32;//Size of each axis.
unsigned char *voxels = new unsigned char[(size * size * size)/8];

Итак, каждая ось имеет длину 32 единицы, но я храню информацию о вокселях на бит. То есть, если бит включен (1), что-то есть, и что-то должно быть нарисовано.

У меня есть пара функций:

TurnOn(x,y,z);
TurnOff(x,y,z);

чтобы включить или выключить местоположение вокселя. (Помогает работать с битами).

После выделения ландшафта я запускаю перлин-шум и включаю или выключаю биты.

У моего класса местности есть еще одна функция - извлечь номер дела "Марширующие кубики" (0-255) из местоположения x, y, z:

unsigned char GetCaseNumber(x,y,z);

путем определения, включены или выключены соседи этого вокселя. Здесь нет проблем.

3) Отрисовка детали

Я делаю циклы для каждой оси, извлекаю номер случая, затем получаю предварительно вычисленные треугольники для случая, перевод в координаты x, y, z и рисование этих треугольников. Здесь нет проблем.

Итак, результат выглядит так:

terrain

Но, как вы можете видеть, в любом месте разрешение не сравнимо, например, с этим: MC http://www.angelfire.com/linux/myp/MCAdvanced/mcnormal.gif

Я видел в примерах MC, что люди используют то, что называется "изо значения", что я не понимаю. Любые предложения, как улучшить мою работу, или каковы значения iso, и как реализовать ее в единой сетке, были бы по-настоящему хороши.

1 Ответ

8 голосов
/ 05 января 2012

Проблема в том, что ваши вокселы являются бинарной маской (просто включена или выключена).

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

Гладкий пример, вероятно, генерируется из гладких скалярных данных.

Представьте, что если ваши данные плавно колеблются между 0 и 1,0, и вы устанавливаете порог на 0,5.Теперь, после того, как вы определите, какой конфигурации является данный куб, вы смотрите на все сгенерированные вершины.

Скажем, у вас есть вершина на ребре между двумя вокселями, один со значением 0,4, а другой 0,7.Затем вы перемещаете вершину в положение, где вы получите точно 0,5 (порог) при интерполяции между 0,4 и 0,7.Так что это будет ближе к вершине 0,4.

Таким образом, каждая вершина точно находится на интерполированной изо-поверхности *1011*, и вы получите гораздо более гладкие треугольники.

Но для этого требуется, чтобы ваши входные воксели были скалярными (и плавно изменялись).Если ваши вокселы имеют двухуровневый уровень (все 0 или 1), это приведет к появлению тех же треугольников, которые вы получили ранее.

Другая идея (не ответ на ваш вопрос, но, возможно, полезный):

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

...