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?
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.
fuente
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 .
fuente