Какую структуру данных следует использовать для представления ландшафта вокселей?


18

Согласно странице Википедии о вокселях, «[...] положение вокселя определяется на основе его положения относительно других вокселей (т. Е. Его положения в структуре данных, которая составляет одно объемное изображение)».

Как реализовать такую ​​структуру данных? Я думал об октрее, но мне интересно, есть ли что-то еще, о чем я никогда не слышал.


1
Это довольно сложный вопрос, потому что он очень зависит от того, какие данные понадобятся вашим воксельным данным. Такие вещи, как заполнение вокселя, как он выглядит и т. Д., Будут зависеть от того, что вы делаете. Во-вторых, структура данных должна обеспечивать высокоскоростной доступ для манипулирования данными в реальном времени и последующего их обновления. Как поддерживать низкую структуру памяти для каждого вокселя, а быстрый доступ / манипулирование данными - в значительной степени ключевые технические проблемы, которые довольно конкретное намерение при работе с воксельными двигателями. Не ответ, а комментарий.
Джеймс

Ответы:


14

Первый. Давайте напишем, что мы знаем о каждом вокселе:

voxel = (x, y, z, color) // or some other information

Общее хранение

Общий способ таков:

set of voxels = set of (x,y,z, color)

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

Это должно быть хорошо для простых данных. Но это ни в коем случае не быстрая структура данных.

Рендеринг AFAIK осуществляется по алгоритму сканирования. Статья Tom's Hardware о вокселях содержит изображение алгоритма сканирования .

Быстрый поиск

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

array [x][y][z] of (color)
  • Это имеет O (1) для поиска вокселя по координатам x, y, z.

  • Проблема состоит в том, что его требования к пространству составляют O (D ^ 3), где D - диапазон каждого числа x, y и z (забудьте реальное число, поскольку, если бы они были символами с диапазоном 256 значений, было бы 256 ^ 3 = 2 ^ 24 == 16 777 216 элементов в массиве).

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

Если проблема в хранении

Одним из методов является использование сжатия RLE в массиве. Представьте себе фрагмент вокселей (набор вокселей, где вокселы имеют одно значение постоянной координаты ... например, плоскость, где z = 13). Такой кусок вокселей будет выглядеть как простой рисунок в MSPaint . Воксельная модель, я бы сказал, обычно занимает долю всех возможных мест (пространство D ^ 3 всех возможных вокселей). Я полагаю, что «взять пару из тройки координат и сжать оставшуюся ось» сделает свое дело (например, возьмите [x] [y] и для каждого элемента сожмите все вокселы на оси z при заданных x, y .. . должно быть от 0 до нескольких элементов, RLE будет хорошо здесь):

array [x][y] of RLE compressed z "lines" of voxel; each uncompressed voxel has color 

Другой метод решения проблемы хранения - вместо массива использовать древовидную структуру данных:

tree data structure  = recursively classified voxels
for octrees: recursively classified by which octant does voxel at (x,y,z) belong to
  • Октри, как упомянул Ник. Это должно сжать вокселей. Octree имеет даже приличную скорость для поиска, я думаю, это какой-то O (log N), где N - количество вокселей.
  • Octree должен иметь возможность хранить прилично произвольные данные вокселей.

Если воксели - это упрощенная карта высот, вы можете хранить только это. Или Вы можете сохранить параметры для функции, которая генерирует карту высот, иначе говоря, генерировать ее ...

И конечно Вы можете комбинировать все возможные подходы. Но не переусердствуйте, если только вы не проверите, что ваш код работает, и измерите, что он ДЕЙСТВИТЕЛЬНО быстрее (так что это стоит оптимизации).

TL; DR

Кроме Octrees - это сжатие RLE с вокселями, google "voxlap", "ken silverman" ...

Ресурсы

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


1
«Если проблема с хранилищем»: вы также можете использовать VTC ( oss.sgi.com/projects/ogl-sample/registry/NV/… ) или DXT сжатие
KindDragon

@ KindDragon спасибо за эту информацию. :) Это очень хорошая идея.
user712092

Ссылка на ресурс недоступна.
Иезекииль

4

Есть два разных аспекта структуры данных, о которых они могут говорить.

Структуры массивов

Когда вы ссылаетесь на элемент массива любого числа измерений, учтите, что сам массив, как только вы передадите индексы (например myArray[4][6][15]), знает, что находится в этом месте. Если то, что находится в этом месте, является вокселем, то этому вокселю не нужно дополнительно записывать свои собственные координаты x, y и z - массив, содержащий воксель, неявно указывает свое местоположение в мире на основе его индексации по массиву.

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

Octrees

(Я отмечаю это второе, потому что это менее вероятно, что то, на что ссылается Википедия, и реализации вокселей не требуют использования октодеревьев, хотя почти все современные используют октуды.)

Корневой узел октодерева - это отдельный неделимый куб. Давайте создадим пример. Скажем, корень вашей октры, самый центр куба, находится {0, 0, 0}в трехмерном пространстве. Как только вы начинаете размещать объекты в этом пространстве (читай: более одного объекта), настало время разделить октре далее. Здесь вы делите на 8 ( окт ), разрезая его, используя 3 плоскости, причем эти плоскости являются плоскостями xy, xz и yz. Ваш оригинальный куб теперь содержит ровно 8 кубиков меньшего размера. Каждый из этих подузлов позиционируется как смещение от центрального родительского куба . То есть, например, куб, лежащий в положительном октанте xyz, будет иметь смещение от центра родительского / содержащего куба точно{root.width / 4, root.height / 4, root.depth / 4}, Вместо того, чтобы указывать абсолютную позицию для каждого подузла, логичнее рассматривать родительский узел как источник его дочернего пространства. Это то же самое, что графы сцены работают.

Достаточно просто увидеть это на двухмерном чертеже, где вы рисуете квадрат и подразделяете его на 4 равные области. Если бы, как и в случае с нашим корневым узлом, центром родительского квадрата считались {0, 0}, то 4 центра дочерних квадратов

{root.width / 4, root.height / 4}, {-root.width / 4, root.height / 4}, {root.width / 4, -root.height / 4}, {-root.width / 4, -root.height / 4}

... По отношению к родителю - тот же принцип, что и в 3D.


Спасибо за ваш ответ. В моем случае, некоторые большие части ландшафта были бы сделаны из одного и того же типа вокселя, поэтому я думал о октреях (большой кусок не нужно было бы подразделять). Тем не менее, я сделаю снимок трехмерного массива, поскольку он выглядит проще в реализации. Я уверен, что мне удастся абстрагировать детали реализации моего класса terrain достаточно, чтобы не было так сложно переключать реализации в случае необходимости.
pwny

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

Как дальнейшее чтение, хорошее обсуждение реализации октодеев, включая несколько полезных ссылок, можно найти в статье Intel Расширение STL для игр .
Мартин Фут

1

Вы можете использовать RLE. Но вы можете использовать SVO (Sparse Voxel Octree), id Tech 6 использует SVO. SVO - это технология рендеринга трехмерной компьютерной графики, использующая подход с лучевой передачей или иногда с трассировкой лучей в представлении данных октодерева.

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

Используйте raycasting, потому что это быстрее.


0

Как правило, вы можете избежать 3D-структуры данных для местности. Вместо этого вы можете использовать карту высот . Это может быть очень дешево и эффективно вокселизировано во время выполнения. Обычно (по моему опыту) платит за отслеживание минимальной высоты, которую вам нужно визуализировать в каждом столбце, а также иногда углов начала-остановки-верха, чтобы вы также могли отбрасывать столбцы с задним торцом.

Вот один, который я сделал очень давно: http://sites.google.com/site/williamedwardscoder/spinning-voxels-in-flash

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

Разреженные воксельные представления того стоят, когда у вас большие настоящие воксельные миры. Джон Кармак говорит их последние несколько лет ...


Я тоже подумала о картах роста, но некоторые вещи оттолкнули меня от них. Дело в том, что в моем случае местность не очень большая или очень сложная (например, местность типа лабиринта, очень декартова). Я также хотел бы, чтобы часть местности была разрушаемой или позволяла пользователю воздействовать на местность посредством строительства. Это может привести к тому, что игрок создаст «туннели» на местности, которые кажутся более сложными для представления с помощью карты высот.
pwny
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.