Marching Cubes Part 5: Level of detail switching with marching cubes
This is the fifth part of a series on marching cubes. This time we will make it possible to switch between the level of detail while ensuring that previous terrain edits are kept and displayed.
1. Switching Level of detail
In the last part we made it possible to select a resolution for our terrain, however there are 2 problems:
When switching between LOD, the mesh does not take into account previous edits.
When a new LOD is selected, we regenerate the entire chunks noise.
In this part we will fix these issues by generating the maximum amount of noise for the chunk at the start and reuse this generated noise for all other LODs.
1.1 Reusing noise
Before being able to reuse noise, we need to settle on a number for the maximum amount of noise within our chunk. The amount of points within our last LOD seems like the most appropriate choice.
Add a variable to GridMetrics to access the last lod easily.
In the chunk class we now need to give the noise generator the last LOD, since we want the maximum amount of noise. Let’s also make sure this noise is generated just once.
Of course, if we have a fixed amount of noise returned regardless of selected LOD, we must also initialize the weights buffer with this fixed number.
The count of triangles will remain the same, as we still use a variable amount of triangles given a LOD.
When in playmode, we now get noise similar to following:
When the last LOD is selected in the inspector everthing still works as normal, the problem is that currently we assume that the chunk size is equal to the size of our selected LOD, causing the noise values that are sampled within the marching cubes algorithm to be all over the place, as the noise array within the marching cubes compute has a size of the last LOD.
So, when constructing our mesh, we need to tell the maching cubes compute that the chunk size is always the same.
Again in playmode, we now see that while we generate the right amount of triangles given our LOD, we do not scale the mesh correctly nor do we sample the noise at the right locations.
Let’s start by scaling correctly. For this we need to know what the chunk size given an LOD is once again. Call this the “LODSize”.
Now, in the marching cubes compute, create the appropriate variable.
And instead of scaling the mesh relative to the chunk size (which at this point represents the maximum possible chunk size). Scale it relative to the LODSize.
1.2 Sampling noise
At this point we again scale our mesh correctly. However our scaled mesh is not actually using the right noise values. When using LOD 0 (Points Per Chunk = 8), we only use the first 8 noise values in any given dimension (xyz) out of the entire noise grid.
To sample the right noise values, we must scale these points so that they take up the entire grid size. For example: When using LOD 0 (Points Per Chunk = 8), we must scale all points within the 3D grid relative to the last LOD (Points Per Chunk = 40). This means that the point (1,1,1) must actually represent point (5,5,5). To get this new point, we use the following formula:
Let’s define the scale factor in the Chunk script.
Back in marching cubes compute we now have to apply the scale factor to our id (where the id represents a position between (0,0,0) and (lod size, lod size,lod size)).
Let’s also not forget to change the bounds of the id to LOD Size instead of chunk size.
Adjust the cube values so they sample the right position.
In game we now find that our mesh contains many gaps.
The problem is that an addition of 1 no longers samples the next cube corner, we now also need to scale the 1.
1.3 Fixing terrain editing
Finally, we need to fix the terrain editing. When the last LOD is selected in the inspector, there seems to be no problem, we can edit the terrain just fine. When in any other LOD, we get either no edits at all or very strange edits.
The solution is to always use the last lod when editing weights.