- Home /
Implementation and Optimisation of Noncuboidal Voxel Objects
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'.
So why doesn't importing blender meshes into Unity and instantiating them do the job?
Doing what you suggested definitely works, and I'd be happy to accept it as an answer if you reckon it's a good practice here. I think what's got me confused is how 'best' to do this kind of stuff in terms of optimisation, as I'll have to simultaneously render quite a sizable amount of these fluff objects and even when I render unoptimised, individual game object cubes like this it already results in a nasty performance hit. Every unity implementation of marching cubes I've seen generates the mesh through script, so working on the assumption that each possible mesh piece works on a vaguely similar principle to that, I guess I sort of asked myself if there's something they know that I don't.
On the other hand, how would the coding and instantiating methods compare when it comes to combining meshes? An optimised voxel chunk would constantly generate a mesh that's already culled, combined and so on. When instantiating I guess I'd have to do that stuff afterwards to achieve a similar result, but I'm not sure how I'd be able to optimise beyond culling whole game objects that I know are totally obscured, and I've not tested if it'd actually be faster to constantly combine all similar, visible, instantiated objects at runtime rather than using the scripted way that kind of already does that.
I hope some of that makes sense at least - It's 1.40am here and I'm tired, so there's a decent possibility I've just missed something rediculously obvious and am now just rambling.
Answer by Bunny83 · Dec 01, 2016 at 01:48 AM
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.
I really appreciate you taking the time to come up with such a good response.
I've built cubic voxel systems before, so although I'm familiar with how to use chunks and why, you laying out the pros and cons kind of helped put it in perspective, so I think I've got a better idea of how to tackle this now. The main difference here between my scenario and $$anonymous$$inecraft and co. is that I'm not trying to use this for generating terrains, only for player built architecture that just gets superimposed on a standard heightmap based terrain, so I have something of a luxury of being able to use very small chunks. As you say, it's nice to be able to use voxels to manage placement of assets, so based on your input I think I'll push for that approach with the assumption that besides reduction of draw calls the main gain will be convenience.
As for occlusion culling, I wasn't really thinking of Unity's, but more the kind of techniques you mentioned such as ignoring any voxels that aren't adjacent to a transparent voxel. Either way you're right - there's not really much benefit here unless the weird shaped blocks are still totally opaque on at least one side. That however could be arranged as I design them.
Thanks again for you help!
Your answer
Follow this Question
Related Questions
Editing Terrain Topology at Runtime 0 Answers
On combining two objects to reduce draw calls ... 3 Answers
Mesh Collider for Voxels 1 Answer
How would i go about meshing over several objects? 1 Answer
Generate mesh based on 3d array. 1 Answer