Voxel Terrain Part 2 - Voxelization Methods
Instead of settling for one way only to voxelize a terrain I decide to make it possible to select between a few of them depending on what was required. They're are basically just two methods, forward or backward.
enum VoxelMethod { VOXEL_METHOD_FORWARD, VOXEL_METHOD_FORWARD_CONTOUR, VOXEL_METHOD_BACKWARD, VOXEL_METHOD_BACKWARD_CONTOUR };
Forward starts with a parent node and checks each corner against some function that says if the corner is above or below some user defined surface. If the node has been determined to represent some part of the surface it is subdivided into eight new nodes and the process repeated until the lowest subdivision level is achieved.
Backward creates a 3D grid of points that are iterated through in a three layer nested for loop. The points are spaced at the lowest node size required (1m cubed in this case) and then tested with the same user defined function for forward voxelization. The points and then looped through again to find which ones represent the surface and then the parent node is subdivided until it reaches the node that represents these points. It starts from the end and works it's way back.
As shown here the forward method is fast but in most cases leaves a few holes in the mesh as stated in my previous entry. I've left the method in there because it might be useful in some situations.
Here is the result from using the backward method. Ignoring the bounds of the terrain you can see there are no more holes in the surface. I haven't done any speed comparisons yet but for this small 128x128x128 terrain I can't tell a difference. It also uses a bit less memory too than the forward method. Most likely due the fact only the nodes that represent the surface are actually created. This was a feature I removed from the forward method because it made more holes with it than without it, but it could be re-introduced later know that I know what the issue is.
A view from inside looking out.
This leads me to the small floating fragments caused by using 3D noise and the potential resolution by the contouring method. I'm thinking in either the forward or backward case, when a surface is found it will start to follow the surface by calculating where it might be based on the surface it's already found. This should mean that only a surface connected the previous nodes surface will actually be created. It may even be faster due to it only having to sample the noise when it knows it's close to it. The issue though is first determining which surface is the main surface, otherwise it could find the small fragment first (pictured) and class that as the main surface and therefore disregarding the larger main surface. This requires more thought.
Next though I am going to work on render methods.
enum RenderMethod { RENDER_METHOD_MARCHING_CUBES, RENDER_METHOD_TRANS_VOXEL, RENDER_METHOD_CUBOID, RENDER_METHOD_SURFACE_NETS, RENDER_METHOD_DUAL_CONTOURING };
- 1
5 Comments
Recommended Comments