For a long time I've been wanting to make my own voxel system from scratch in Godot, even managing some successful experiments with which I got a hang of the way voxels work. Yet the more I learn the deeper I'm tempted to dive, in terms of creating the perfect voxel system as optimized as possible, getting as many voxels for the best FPS and loading time with as large of a draw distance. My last attempt at a voxel engine got me to support 0.5m voxels over the 1m Minecraft standard decently, even with a LOD system for chunks. Then I discovered the new world of small voxels, where at Minecraft's texture resolution you get the geometry level of one cube per pixel: Now I'm telling myself that if I'd rather spend time on such a system, it should be one capable of achieving those small resolutions.


Of course there's a big problem, this wouldn't be a help thread otherwise. While the cube concept is the same code wise just at a smaller scale, the optimizations and techniques need to be completely different. 1m voxels are doable using standard geometry based on faces made of triangles, these days you can have that no problem. But once we're talking resolutions of 0.0625m (1/16) that's more than a dozen times the amount of triangles... no GPU is able to render that decently even if you use one cube with mesh instancing, you'd be lucky to get 10 FPS on a powerful computer with a draw distance where you barely see what's in front of you. As others pointed out a technique different from the conventional triangles the GPU works with is needed... problem is what would that technique be, especially in an engine like Godot built to work with conventional triangles?

Only alternative that comes to mind is shaders. And I don't mean geometry being generated by the GPU, your graphics card would still be rendering potentially millions of faces at a time no matter what produced those faces. The salvation would be a shader which creates the illusion of geometry within an area: I've seen fractal shaders in a few engines, where you create a large cube and see all sorts of bizarre shapes in it as you move the camera but no real geometry other than this cube is created: This trick could be used to give a shader a list of colors at specific points, which it then uses to simulate little cubes based on the perspective you're looking from... larger chunks are then just boxes textured with this magic material.

But I'm sure many can see the problems with this approach. First is lighting: Each voxel needs to receive light and cast shadows, the shader would need to not just read but also output to the lighting system to trick it into seeing real geometry. Once that's solved we have the issue of collisions and pathfinding and occlusion culling, those can only ever run on the CPU and must use a box entity per voxel which will be just as costly again. It gets even more complicated if we dive into ideas like supporting transparent or reflective or emissive 3D pixels like I'd want it to.

I'm definitely interested in seeing such a shader that works in Godot 4 still: If you're aware of one please feel free to share! Whether it's a shader based approach or other solution that manages to get it done with triangles, I'm curious what is possible so far: Have any attempts been made to create an engine for tiny voxels, where every pixel is its own little block and individually destructible? How far did you get and what was the best performance you could achieve?

  • xyz replied to this.

    xyz That is interesting to know. Now I'm curious how many instances of a mesh have been tested in Godot 4, with GPU mesh instancing obviously so they're the same VBO data: How many cube mesh nodes are you able to render on your screen at once before FPS starts to go bad? 10.000... 100.000... 1.000.000? Maybe it's safe to do this the simple way and I'm just overthinking it, especially as each voxel would act as an occluder for the builtin occlusion culling and I might even retain some kind of resolution LOD.

    Another thing I was undecided on: I'm no longer planning on building the mesh myself, that actually seems to be less optimal... I'd prefer having each voxel as a node at this point. In that case I wonder which is best: Using a single cube mesh per voxel, or creating 6 different plane meshes which are selectively hidden in between voxels that neighbor each other? The later initially seemed ideal as faces in between neighbors are explicitly derendered, but having one cube as a single mesh could be more optimal than 6 plane meshes even if they too would be a single mesh definition and instance?

    • xyz replied to this.

      MirceaKitsune For start you should look into how Minecraft does things, including all optimizations, and implement that. Then stress test it and see what can be done further.

        xyz I do know at least the basics of it. This is a very different engine and time from Minecraft though: Godot likely structures data differently, it would be interesting to know the little details on how that can be used to optimize even further. Like is using a box node per voxel faster than generating the mesh yourself? Once I get to testing it I'll find out more of course.

        • xyz replied to this.

          MirceaKitsune You should probably not use nodes at all but instead build meshes directly via RenderingServer and use as much instancing as possible.

          With tiny voxels, having a good LOD strategy may be the most important thing for optimization.

          Just a quick sidenote, the term I think you want to be using when doing research is texel not pixel. A quick search for 'raymarch texel space' brought me to this as one of the first results for an example.