Otimizando uma malha para paisagens de cubos de voxel

12

Brincando com a criação de paisagens mundiais minecraft / lego no Unity 3D (paisagens de voxel geradas proceduralmente com cubos), estou descobrindo que as malhas criadas para essas paisagens ocupam MUITA memória. A malha atualmente consiste apenas de vértices para os lados visíveis de um cubo. O uso da memória para um terreno complexo pode demorar 6 ou 7 cem megas.

Essas malhas podem ser otimizadas, mas estou lutando para encontrar um algoritmo decente para fazer isso.

O algoritmo deve levar em consideração que você não deseja "mesclar" blocos de diferentes tipos de terreno. Eu acho que um começo realmente simples pode ser apenas processar todos os blocos ao longo de um eixo e fazer varreduras extras para os outros dois eixos.

Preciso manter a forma da malha, que não é a fusão de vértices, a ponto de o espaço vazio ou sólido ser alterado. O motivo é que pode haver criaturas / etc que ainda precisam navegar pela malha. Portanto, não posso simplesmente criar uma malha distorcida com detalhes realmente baixos.

Quaisquer pensamentos / sugestões / dicas sobre isso?

James Livingston
fonte
2
Por que você está armazenando vértices para um cubo de tamanho conhecido? Faça algoritmicamente; ou use um buffer de vértice compartilhado.
Deceleratedcaviar
Por que malha poligonal? O Voxel pode ser renderizado com bastante eficiência, exatamente como eles são . Para um cubo de voxel, você precisa de 3 elementos flutuantes (x, y, z), para 1 caixa Você precisa de cerca de 8 * 3 elementos flutuantes (8 vértices) e, caso tenha bordas e polígonos implícitos. Talvez o Unity não seja a ferramenta para esse problema de voxel.
user712092

Respostas:

5

Minha pergunta é:

Por que você precisaria da própria malha para fazer o movimento da criatura?

Você não pode fazer o cálculo do caminho em uma matriz 3d de IDs?

Eu acho que o Minecraft usa uma matriz 3D com 4 bits de bloco PR. Também simula criaturas com um certo raio ao redor do jogador.

Você pode armazenar seus pedaços em uma estrutura oc-tree, onde cada pedaço é compactado.

Se você mantiver os dados compactados na RAM, poderá descomprimir os dados rapidamente, quando necessário.

texto alternativo

Nailer
fonte
Eu estava confiando em ter a malha para a detecção de colisão integrada com o Unity, mas não há nada que me impeça de apenas testar colisão / desvio em uma estrutura de dados personalizada. No entanto, ainda preciso criar uma malha visível para exibir o terreno, e é isso que preciso otimizar.
James Livingston
Outro ponto ... como você pode ver na captura de tela ... não há muito terreno plano. As malhas geralmente são superfícies ásperas de cubos, mas acho que há espaço para otimizar as faces / vértices da malha. Parece que uma octree seria melhor para dados com muitos blocos de dados semelhantes, em vez de dados "irregulares". Ou isso não está correto?
James Livingston
@ Gatorfrog: Lembre-se, o espaço vazio também é um dado. se estiver irregular, com certeza, haverá muitos bits sinalizando seu vazio. O octree está aí para você descobrir quais pedaços você deve descompactar antes de renderizá-los. O espaço vazio será apenas um monte de zeros. Meu trabalho diário envolve trabalhar com uma biblioteca de renderização voxel muito sofisticada. Meu próximo post descreverá o que eles fazem.
Prego Nailer
A biblioteca com a qual trabalho faz o seguinte: Cria blocos de dados e os armazena em um banco de dados de arquivos simples. Cada pedaço tem um ID. Cada cubo consiste em muitos pedaços. Para cada pedaço, é criado um certo número de níveis de detalhe. Onde o nível mais alto de detalhes possui 100% dos voxels, o segundo mais alto possui 25% de todos os voxels e depois divide por 4 todos para cada nível subseqüente. Os pedaços próximos a você podem ser visualizados usando o mais alto nível de detalhe.
Nailer
todos os dados são enviados de forma compactada da RAM para a VRAM, onde são inflados pelos algoritmos de compactação GPGPU em execução no CUDA. Isso economiza muita largura de banda de memória. Portanto: verifique onde o jogador está e obtenha altos níveis de detalhes, as coisas mais distantes podem ser facilmente visualizadas usando um dos LODs inferiores.
Nailer
1

Que tal usar um octree para armazenar o terreno?

Por exemplo, ar = nenhum nó, todos os outros tipos de terreno teriam um nó com o tipo de terreno.

Ao inserir / remover nós, você pode verificar se todos os oito filhos de cada nó no caminho da árvore modificado têm o mesmo tipo de terreno e mesclá-los, se necessário. Dessa forma, grandes blocos do mesmo material ocupariam apenas um nó.

Exilyth
fonte
0

Você está criando apenas os cubos para partes da geometria que o jogador pode ver? Esse seria o meu primeiro passo. Dependendo do tamanho do seu terreno, você não precisa ter o mundo inteiro carregado / desenhado / visível / o que seja.

Tetrad
fonte
Estou apenas criando a malha para lados de cubos que têm ar vazio ao lado deles. Na medida em que não desenha malhas que o jogador não pode ver ... pensei em excluir todos os pedaços que não tinham blocos visíveis, como cavernas subterrâneas ou buracos que levavam ao chão em ângulo. Definitivamente, eu não seria capaz de confiar nas minhas malhas para colisão / pathing naquele momento.
James Livingston