Марширующие кубики, воксели, нужно немного предложений
Я пытаюсь построить надлежащую разрушаемую местность, только для исследовательских целей. Ну, все прошло хорошо, но разрешение меня не удовлетворяет. Я видел много примеров того, как люди реализуют алгоритм MC, но большинство из них, насколько я понимаю, использует функции для триангуляции конечной сетки, что мне не подходит.
Я постараюсь кратко объяснить, как я строю свою местность, и, возможно, кто-то из вас подскажет, как улучшить или увеличить разрешение окончательной местности.
1) Предварительный расчет треугольников МС.
Я запускаю простой цикл просмотра таблиц 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 и рисую эти треугольники. нет проблем здесь.
Итак, результат выглядит так:
Но, как вы можете видеть, в любом месте разрешение не сравнимо, например, с этим: http://www.angelfire.com/linux/myp/MCAdvanced/mcnormal.gif
Я видел на примерах MC, что люди используют то, что называется "изо значения", что я не понимаю. Любые предложения о том, как улучшить мою работу, или каковы значения ISO, и как реализовать ее в единой сетке, были бы по-настоящему хороши.
1 ответ
Проблема в том, что ваши воксели представляют собой бинарную маску (просто включена или выключена).
Это отлично подходит для алгоритма марширующих кубов "по умолчанию", но это означает, что вы получаете острые края в своей сетке.
Гладкий пример, вероятно, генерируется из гладких скалярных данных.
Представьте, что если ваши данные плавно колеблются между 0 и 1,0, и вы устанавливаете порог на 0,5. Теперь, после того, как вы определите, какой конфигурации является данный куб, вы смотрите на все сгенерированные вершины.
Скажем, у вас есть вершина на ребре между двумя вокселями, один со значением 0,4, а другой 0,7. Затем вы перемещаете вершину в положение, где вы получите точно 0,5 (порог) при интерполяции между 0,4 и 0,7. Так что это будет ближе к вершине 0,4.
Таким образом, каждая вершина находится точно на интерполированной изо-поверхности, и вы получите гораздо более гладкие треугольники.
Но это требует, чтобы ваши входные воксели были скалярными (и плавно изменялись). Если ваши воксели имеют двухуровневый уровень (все 0 или 1), это приведет к появлению тех же треугольников, которые вы получили ранее.
Другая идея (не ответ на ваш вопрос, но, возможно, полезный):
Чтобы получить более плавный рендеринг без математической корректности, было бы целесообразно вычислить средний вектор нормали для каждой вершины и использовать эту нормаль для каждого соединяющегося с ней треугольника. Это скроет острые края.