Марширующие кубы, воксели, нужно немного предложений

Я пытаюсь построить подходящую разрушаемую местность только для исследовательских целей. Ну, все прошло хорошо, но разрешение меня недостаточно удовлетворяет. Я видел много примеров, как люди реализуют алгоритм 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);

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

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

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

unsigned char GetCaseNumber(x,y,z);

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

3) Часть рендеринга

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

Таким образом, результат выглядит следующим образом:

местность

Но, как вы можете видеть, в любом отдельном месте разрешение несопоставимо, например, с этим: MC
(источник: angelfire.com)

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


person Jeffers    schedule 04.01.2012    source источник
comment
разрешение выглядит для меня таким же, за исключением того, что образец не выглядит привязанным к сетке, как у вас.   -  person Mooing Duck    schedule 04.01.2012
comment
Я думаю, вы имели в виду изометрические поверхности. Идея состоит в том, чтобы взять некоторую скалярную функцию поля, например. сфера r(x,y,z) = sqrt(x**2 + y**2 + z**2) и проверка некоторого порогового значения, чтобы решить, находится ли позиция внутри или за пределами определенного порога. В вашей реализации MC вы должны использовать результат r(x,y,z) › t вместо бита заполнения вокселя.   -  person datenwolf    schedule 05.01.2012


Ответы (1)


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

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

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

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

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

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

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

Еще одна идея (не ответ на ваш вопрос, но, возможно, полезная):

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

person Community    schedule 04.01.2012