Gérer les données Voxel


8

Je programme en C ++ comme passe-temps depuis environ 4 mois maintenant, et j'ai vraiment adoré créer des trucs en utilisant des voxels. J'ai écrit un "jeu" (plutôt un défi personnel, car je n'ai vraiment fait que le terrain, pas de gameplay) qui rendait un monde semblable à Minecraft, mais récemment, j'ai pensé à essayer d'écrire un jeu / défi / etc. qui utilise un algorithme comme Marching Cubes ou Dual Contouring et réduit la taille du voxel. Lorsque j'ai écrit mon projet de type Minecraft, j'ai stocké les données de chaque bloc dans un tableau multidimensionnel de courts métrages non signés (me donnant ainsi jusqu'à 65536 types de blocs différents). De plus, pour le rendu, je n'ai stocké qu'un point (en tant que GLubyte) et un autre GLubyte pour indiquer laquelle des 6 faces fait face au point représenté. J'ai ensuite rendu le visage à l'aide d'un ombrage géométrique.

Avec le nouveau projet auquel j'ai pensé, la chose que je ne peux pas comprendre est de savoir comment je peux éventuellement stocker suffisamment de données de voxels pour avoir des voxels d'environ ~ 5 cm ou 10 cm par rapport aux anciens voxels de 1 m que j'avais. Lorsque j'ai rendu une zone de blocs de 704x704x704, mon ancien projet utilisait environ 670 Mo de RAM. Si je réduisais la taille du voxel à 10 cm et conservais la même distance de rendu, cela représenterait environ 649 Go de données Voxel (en supposant 2 octets par voxel et une zone de 7040 ^ 3 voxels). Existe-t-il un moyen de stocker les données de voxel d'une manière plus efficace qui me permette toujours un large éventail de types de voxels différents?

Réponses:


5

Avez-vous besoin d'avoir chaque morceau en mémoire (en supposant que vous utilisez des morceaux) en même temps? Certains seront occlus - en particulier souterrains - ou derrière des montagnes, etc.

Vous pouvez également utiliser un octet LOD ou une structure similaire pour essayer de garder le détail actuellement visible inversement lié à la distance de l'observateur. Comme l'a déclaré Jason, cela est beaucoup plus susceptible de vous acheter des performances, mais c'est un changement structurel majeur par rapport à une carte en morceaux plats.

Voir cet article sur les clipmaps de mon blog préféré (il a un moteur de voxel similaire à ce que vous décrivez avec une taille de voxel de ~ un décimètre).


2
Tout d'abord, oui, j'utilise des morceaux. Deuxièmement, votre suggestion de décharger des morceaux complètement cachés aiderait certainement beaucoup, merci. Juste au-dessus de ma tête, une méthode potentielle que je pourrais utiliser serait d'utiliser une requête d'occlusion avec la boîte englobante du bloc (puisque toutes les tailles de bloc sont connues) pour voir si un bloc est visible, et charger / décharger un bloc en fonction du résultat. Modifier: Je viens de voir votre modification et j'ai déjà vu ce blog. C'est la raison pour laquelle je veux expérimenter avec une taille de voxel plus petite =)
Shadow

L'occlusion est beaucoup moins importante que LOD. L'occlusion ne vous apporte rien à moins que vous ne soyez sous terre ou que vous regardiez le flanc d'une montagne. LOD en soi vous permet de rendre une planète entière. Les requêtes d'occlusion sont une mauvaise idée, car elles introduisent un aller-retour GPU-> CPU-> GPU. Le rendu conditionnel est cependant viable, mais le CPU peut probablement suffire à lui seul.

Bon point. Je viens de dire LOD deuxième parce que c'est un changement structurel majeur.
ThorinII

3

L'approche standard pour des moteurs comme le VoxLap de Ken Silverman et son successeur Ace of Spades, consiste à utiliser la compression RLE et plusieurs autres astuces au niveau du bit pour à la fois stocker et accéder aux données. Ce type de compression 1D a tendance à être très efficace et considérablement plus facile à utiliser que les octrees. Je crois que le moteur de Silverman a atteint une résolution de voxel de quelque chose comme 10 cm cube. Quelque chose que vous ne voyez pas couramment aujourd'hui, et qui a été réalisé sur un matériel beaucoup plus faible.

Je crois qu'il est également vrai que son approche n'a pas stocké les couleurs des voxels non exposés, qu'elle a plutôt calculé la couleur des voxels de surface en fonction de la hauteur, ou en se souvenant des zones du terrain qui avaient été dynamitées et en les colorant comme du "sol frais". ". Vous pouvez utiliser une sorte de fonction continue comme le bruit perlin pour ce faire, mais cela pourrait rapidement coûter cher pour de grandes surfaces (sauf si, peut-être, effectué sur le GPU).

Les octrois ne sont pas mauvais, mais ils sont difficiles à utiliser dans la pratique, et l'allocation efficace en cache est considérablement plus difficile que RLE, qui est facile à linéariser par bloc. L'article fondateur de Tero Karras et Samuli Laine sur les SVO indique à quel point les efforts sont investis dans une mise en œuvre octree vraiment performante - et qui ne considère que le rendu, pas le gameplay ou les communications réseau.


0

Je ne sais pas jusqu'où vous êtes allé dans votre projet, mais moi et un de mes amis utilisons l' algorithme Dual Marching Cubes , basé sur la structure de chunck Octree et utilisant une double grille pour restituer les données. Il présente de nombreux avantages, comme une très faible mémoire requise et un rendu très rapide. Il peut être un peu difficile d'implémenter le niveau de détail (LOD) dans les bordures de blocs avec d'autres blocs, mais si vous avez du temps libre, vous pouvez découvrir comment les développeurs Ogre3D ont fait .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.