Optimizando una malla para paisajes de cubos voxel


12

Jugando con la creación de paisajes mundiales de minecraftish / lego en Unity 3D (paisajes voxel generados por procedimientos con cubos), descubro que las mallas creadas para estos paisajes ocupan MUCHA memoria. La malla actualmente solo consiste en vértices para los lados visibles de un cubo. El uso de la memoria para un terreno complejo puede tomar 6 o 700 megas.

Estas mallas podrían optimizarse, pero estoy luchando por encontrar un algoritmo decente para hacer esto.

El algoritmo debe tener en cuenta que no desea "fusionar" bloques que son de diferentes tipos de terreno. Supongo que un comienzo realmente simple podría ser simplemente procesar todos los bloques a lo largo de un eje y hacer barridos adicionales para los otros dos ejes.

Necesito mantener la forma de la malla, que no es la fusión de vértices hasta el punto en que se cambia el espacio vacío o sólido. La razón es que puede haber criaturas / etc. que todavía necesiten navegar alrededor de la malla. Por lo tanto, no puedo crear una malla distorsionada con detalles realmente bajos.

¿Alguna idea / sugerencia / consejo sobre esto?


2
¿Por qué está almacenando vértices para un cubo de tamaño conocido? Hazlo algorítmicamente; o use un búfer de vértices compartido.
deceleratedcaviar

¿Por qué malla poligonal? Voxel se puede representar de manera bastante eficiente tal como son . Para un cubo de vóxeles Necesitas 3 flotadores (x, y, z), para 1 caja Necesitas alrededor de 8 * 3 flotadores (8 vértices), y eso en caso de que tengas bordes y polígonos implícitos. Quizás Unity no sea la herramienta para este problema de vóxel.
user712092

Respuestas:


5

Mi pregunta es:

¿Por qué necesitarías la malla para hacer el movimiento de la criatura?

¿No puedes hacer el cálculo de ruta en una matriz 3d de id?

Creo que Minecraft usa una matriz 3D con 4 bits de bloque pr. También solo simula a las criaturas un cierto radio alrededor del jugador.

Puede almacenar sus fragmentos en una estructura de árbol oc, donde se comprime cada fragmento.

Si mantiene los datos comprimidos en la RAM, puede descomprimirlos con bastante rapidez cuando sea necesario.

texto alternativo


Estaba confiando en tener la malla para la detección de colisión integrada con Unity, pero no hay nada que me impida simplemente probar la colisión / ruta contra una estructura de datos personalizada. Sin embargo, todavía necesito crear una malla visible para mostrar el terreno, y esto es lo que necesito optimizar.
James Livingston el

Otro punto ... como puedes ver en la captura de pantalla ... no hay mucho terreno plano que sea plano. Las mallas son generalmente superficies rugosas de cubos, pero creo que hay espacio para optimizar las caras / vértices de la malla. Parece que un octree sería mejor para datos que tienen muchos bloques de datos similares, en lugar de datos "irregulares". ¿O esto no es correcto?
James Livingston el

@Gatorfrog: Recuerde, el espacio vacío también es un dato. si es irregular, entonces seguro, habrá muchos bits que indican que está vacío. El octree está allí para que usted pueda descubrir qué trozos debe descomprimir antes de renderizarlos. El espacio vacío será solo un montón de ceros. Mi trabajo diario implica trabajar con una biblioteca de renderización de vóxeles muy sofisticada. Mi próxima publicación describirá lo que hacen.
Nailer

La biblioteca con la que trabajo hace lo siguiente: Crea fragmentos de datos y los almacena en una base de datos de archivos planos. Cada fragmento tiene una identificación. Cada cubo consta de muchos trozos. Para cada fragmento se crean un cierto número de niveles de detalle. Donde el nivel más alto de detalle tiene el 100% de los vóxeles, el segundo más alto tiene el 25% de todos los vóxeles y luego se divide por 4 para cada nivel posterior. Los fragmentos que están cerca de usted pueden visualizarse utilizando el nivel más alto de detalle.
Nailer

Todos los datos se envían en forma comprimida desde la RAM a la VRAM, donde los algoritmos de compresión GPGPU se ejecutan en CUDA. Esto ahorra mucha memoria de ancho de banda. Por lo tanto: compruebe dónde está el jugador y obtenga fragmentos de alto nivel de detalle allí, las cosas más alejadas se pueden visualizar fácilmente utilizando uno de los LOD más bajos.
Nailer

1

¿Qué tal usar un octree para almacenar el terreno?

Por ejemplo, aire = sin nodo, todos los demás tipos de terreno tendrían un nodo con el tipo de terreno.

Al insertar / eliminar nodos, puede verificar si los ocho hijos de cada nodo en la ruta del árbol modificado tienen el mismo tipo de terain y fusionarlos si es necesario. De esa forma, los bloques grandes del mismo material solo ocuparían un nodo.


0

¿Solo estás creando los cubos para partes de la geometría que el jugador puede ver? Ese sería mi primer paso. Dependiendo del tamaño de su terreno, no tiene que tener todo el mundo cargado / dibujando / visible / lo que sea.


Solo estoy creando la malla para los lados de los cubos que tienen aire vacío al lado. En cuanto a no dibujar mallas que el jugador no puede ver ... Pensé en excluir cualquier trozo que no tuviera bloques visibles, como cuevas subterráneas o agujeros que conducían al suelo en ángulo. Sin embargo, definitivamente no podría confiar en mis mallas para colisión / ruta en ese momento.
James Livingston el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.