Administrar datos de Voxel

8

He estado programando en C ++ como un pasatiempo durante aproximadamente 4 meses, y realmente me encantó crear cosas usando voxels. Escribí un "juego" (más que solo un desafío personal, ya que realmente solo hice el terreno, sin juego) que generó un mundo parecido a Minecraft, pero recientemente he estado pensando en intentar escribir un juego / desafío / etc. que utiliza un algoritmo como Marching Cubes o Dual Contouring y reduce el tamaño del vóxel. Cuando escribí mi proyecto similar a Minecraft, almacené los datos de cada fragmento en una matriz multidimensional de cortos sin firmar (lo que me dio hasta 65536 tipos de bloques diferentes). Además, para renderizar, solo almacené un punto (como GLubyte) y otro GLubyte para indicar cuál de las 6 enfrenta el punto representado. Luego rendericé la cara usando un sombreador de geometría.

Con el nuevo proyecto en el que he estado pensando, lo que no puedo entender es cómo puedo almacenar suficientes datos de vóxel para tener vóxeles alrededor de ~ 5 cm o 10 cm en comparación con los viejos vóxeles de 1 m que tenía. Cuando rendericé un área de bloques de 704x704x704, mi antiguo proyecto usaba alrededor de 670MB de RAM. Si redujera el tamaño del vóxel a 10 cm y mantuviera la misma distancia de representación, eso sería alrededor de 649 GB de datos de vóxel (suponiendo 2 bytes por vóxel y un área de 7040 ^ 3 vóxeles). ¿Hay alguna forma de que pueda almacenar los datos de vóxel de una manera más eficiente que todavía me permita una amplia gama de diferentes tipos de vóxel?

Sombra
fuente

Respuestas:

5

¿Necesita tener cada fragmento (suponiendo que esté utilizando fragmentos) en la memoria a la vez? Algunos estarán ocluidos, particularmente bajo tierra, o detrás de montañas, etc. Es probable que muchos lotes solo estén vacíos / vacíos y, por lo tanto, podrían marcarse con una bandera.

También podría usar un octod de LOD o una estructura similar para tratar de mantener el detalle actualmente visible inversamente relacionado con la distancia desde el observador. Como dijo Jason, es mucho más probable que esto le ofrezca rendimiento, pero es un cambio estructural importante desde un mapa plano.

Vea este artículo sobre mapas de clip de mi blog favorito (tiene un motor de vóxel similar al que usted describe con un tamaño de vóxel de ~ un decímetro).

ThorinII
fuente
2
En primer lugar, sí, estoy usando trozos. En segundo lugar, su sugerencia sobre descargar trozos completamente ocultos definitivamente ayudaría bastante, gracias. Justo en la parte superior de mi cabeza, un método potencial que podría usar sería usar una consulta de oclusión con el cuadro delimitador del fragmento (ya que se conocen todos los tamaños de fragmento) para ver si un fragmento es visible y cargar / descargar un fragmento Dependiendo del resultado. Editar: Acabo de ver tu edición, y en realidad ya he visto ese blog. Es la razón por la que quiero experimentar con un tamaño de vóxel más pequeño =)
Shadow
La oclusión es mucho menos importante que LOD. La oclusión no te da nada a menos que estés bajo tierra o mirando la ladera de una montaña. LOD por sí solo te permite renderizar un planeta entero. Las consultas de oclusión son una mala idea, ya que introducen un viaje de ida y vuelta GPU-> CPU-> GPU. Sin embargo, la representación condicional es viable, pero la CPU probablemente pueda hacer lo suficiente por sí misma.
Buen punto. Acabo de decir LOD en segundo lugar porque es un cambio estructural importante.
ThorinII
3

El enfoque estándar para motores como VoxLap de Ken Silverman y su sucesor Ace of Spades es utilizar la compresión RLE y varios otros trucos a nivel de bits para almacenar y acceder a los datos. Este tipo de compresión 1D tiende a ser altamente eficiente y considerablemente más fácil de usar que los octrees. Creo que el motor de Silverman logró una resolución de vóxel de unos 10 cm en cubos. Algo que no se ve comúnmente hoy, y que se logró en hardware mucho más débil.

Creo que también es cierto que su enfoque no almacenó colores para vóxeles no expuestos, sino que calculó el color de los vóxeles de superficie en función de la altura, o al recordar qué áreas del terreno se habían abierto y coloreado como "suelo fresco" ". Puede usar algún tipo de función continua como el ruido de perlin para hacer esto, pero rápidamente podría ser costoso para grandes superficies (a menos, tal vez, realizado en la GPU).

Los octrees no son malos, pero son difíciles de usar en la práctica, y la asignación eficiente en caché es considerablemente más desafiante que RLE, que es fácil de linealizar por trozos. El documento seminal de Tero Karras y Samuli Laine sobre SVO indica cuánto esfuerzo se requiere para una implementación de octree verdaderamente eficaz, y eso está considerando solo la representación, no el juego o las comunicaciones de red.

Ingeniero
fuente
0

No sé qué tan lejos ha llegado en su proyecto, pero yo y un amigo mío estamos usando el algoritmo Dual Marching Cubes , basado en la estructura de trozos de Octree y usando una cuadrícula dual para representar los datos. Tiene muchas ventajas, como muy poca memoria requerida y una representación realmente rápida. Puede ser un poco complicado implementar el Nivel de detalle (LOD) en los bordes de fragmentos con otros fragmentos, pero si tiene algo de tiempo libre, puede descubrir cómo lo hicieron los desarrolladores de Ogre3D .

Leggy7
fuente