In many voxel games, detailed objects such as torches, stairs, doors or fences are integrated into the existing layout of more standard voxels such as cubes. In most cases such objects complicate standard optimisations. For example, their non-standard topology results in occlusion culling no longer working on a basis of identifying transitions in opacity of adjacent voxels, such as between air and stone.
Additionally, creating cubes from code is all well and good, as is the case for triangles and friends on account of them only having a handful of vertices in obvious, regular locations (even with marching cubes you can mercifully just copy-paste everything you need), but is there some simple method I’ve overlooked where I can import a bunch of meshes from Blender and directly reference them instead of drawing them by vertex, triangle and face like I’m attempting to create some massochistic self-portrait with nothing but a Logo turtle? I’d rather like to be able to create, adjust and tweak meshes more rapidly than a marching cubes approach would allow.
Therefore based on all this, how can I best integrate such objects into a simple voxel system without having to type a short essay per object, and how then can I optimise them beyond the brute force approach of ‘a pile of game objects’.
I’m not sure if you know how most voxel terrain systems work. The point of “chunking” the terrain is to reduce drawcalls. Minecraft uses 16x16x16 large sections. 16 of those on top of each other make up one chunk (height 256). Each section is drawn seperately
The first problem in Unity is the vertex limit. The worst case scenario for one section is that every block is a transparent block. In other words all voxels in one section are visible at the same time. 16x16x16 == 4096 voxels. If every voxel is just a cube that’s 24 vertices per voxel. 4096x24 == 98304 vertices. A Mesh in Unity can only have 64k vertices since Untiy uses ushort (16 bit) indices.
However that’s not yet the worst case. I’m not sure what (transparent vanilla) block in minecraft has the most vertices, but i know a “fence gate” for example consists of 8 cuboids. So that multiplies the count by 8 again. To cope with that we would need to reduce the chunk size drastically in Unity.
I’m not sure what kind of “objects” you want to import, but the more vertices it has the more likely / quicker you run into problems.
A recent Unity example would be the game “Creativerse”. They actually use 16³ sections, however their terrain only consists of blocks, stairs and slopes as far as i can tell. So there are barely transparent blocks. So the worst case here would be a checkerboard pattern across the section. Though this would half the max blockcount so it’s just about 50k vertices. As far as i can tell they have implemented most dynamic object as seperate objects. So they actually aren’t part of the voxel system.
So, adding arbitrary complex meshes into a voxelsystem doesn’t make much sense as long Unity has the 64k limit. You could theoretically scrap the whole “section” concept and just use as many meshes as needed. However that complicates the management quite a bit and it makes it harder to rebuild an area when something changes.
A seperate system for such dynamical / complex objects might make more sense. So still building the terrain as usual (chunked, splitted in sections) and additionally use a mesh pool system for large dynamic objects for each chunk.
Forget about things like occlusion culling. Unity’s occlusion culling system only works with baked data from the editor. Also determining visibility for a voxel system is much more complicated than just drawing the sections in range. Of course when generating the mesh for a section you would omit voxels / faces which are surrounded by / adjacent to solid blocks.