Primeiro. Vamos escrever o que sabemos sobre cada voxel:
voxel = (x, y, z, color) // or some other information
Armazenamento geral
A maneira geral é simplesmente esta:
set of voxels = set of (x,y,z, color)
Observe que esse trigêmeo (x, y, z) identifica cada voxel de forma única, uma vez que o voxel é um ponto no espaço e não há como dois pontos ocuparem um lugar (acredito que estamos falando de dados estáticos de voxel).
Deve ser bom para dados simples. Mas não é de forma alguma uma estrutura de dados rápida.
A renderização é AFAIK feita pelo algoritmo scanline. O artigo de Tom's Hardware sobre voxels possui uma imagem do algoritmo scanline .
Pesquisa rápida
Se a pesquisa rápida for necessária, a estrutura de dados mais rápida para a pesquisa é o hash (também conhecido como array, mapa ...). Então você tem que fazer hash com isso. Então, ingenuamente, queremos a maneira mais rápida de obter um elemento arbitrário:
array [x][y][z] of (color)
Isso tem O (1) para procurar voxel pelas coordenadas x, y, z.
O problema é que seus requisitos de espaço são O (D ^ 3), onde D é o intervalo de cada número x, ye z (esqueça o número real, pois se fossem caracteres Chars, com intervalo de 256 valores, haveria 256 ^ 3 = 2 ^ 24 == 16 777 216 elementos na matriz).
Mas isso depende do que você quer fazer com voxels. Se a renderização é o que você deseja, provavelmente é essa matriz o que você deseja. Mas o problema de armazenamento ainda permanece ...
Se o armazenamento é o problema
Um método é usar a compactação RLE na matriz. Imagine uma fatia de voxels (conjunto de voxels, em que voxels têm um valor constante de coordenada ... como um plano em que z = 13, por exemplo). Essa fatia de voxels pareceria um desenho simples no MSPaint . O modelo Voxel, eu diria, geralmente ocupa fração de todos os lugares possíveis (espaço D ^ 3 de todos os possíveis voxels). Eu acredito que "pegar um par de trigêmeos de coordenadas e comprimir o eixo restante" faria o truque (por exemplo, pegue [x] [y] e, para cada elemento, comprima todos os voxels no eixo z em x, y .. deve haver de 0 a poucos elementos, o RLE faria bem aqui):
array [x][y] of RLE compressed z "lines" of voxel; each uncompressed voxel has color
Outro método para resolver o problema de armazenamento seria, em vez de matriz, usando a estrutura de dados em árvore:
tree data structure = recursively classified voxels
for octrees: recursively classified by which octant does voxel at (x,y,z) belong to
- Octree, como mencionado por Nick. Deve comprimir voxels. Octree tem até uma velocidade decente de pesquisa, acho que é algum O (log N), onde N é o número de voxels.
- A Octree deve ser capaz de armazenar dados voxel arbitrariamente decentes.
Se os voxels são um mapa de altura simplista, você pode armazenar exatamente isso. Ou você pode armazenar parâmetros para funcionar, o que gera o mapa de altura, também conhecido como procedimento.
E, claro, você pode combinar todas as abordagens possíveis. Mas não exagere, a menos que você teste se seu código funciona e meça REALMENTE mais rápido (por isso vale a pena a otimização).
TL; DR
Além de Octrees, é a compactação RLE com voxels, google "voxlap", "ken silverman" ...
Recursos
Há uma lista de recursos e discussão sobre como fazer renderizador voxel rápido, inclui papéis e código fonte .