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?
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.
la source
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 .
la source