Marching Cubes Progression

Jul 6, 2019 3:50 AM

millerc3

Views

8211

Likes

6

Dislikes

0

June 26 - (idk) First I began with learning how to create a 3D array of voxels and instantiated cubes where I wanted terrain to be generated. Cubes are chosen to be drawn when their individual "isovalue" is lower than the surface threshold (.5f). These cubes represent what I define as nodes in my project - should you decide to check it out.

June 26 - 8:30pm

After a lot of testing with the 3D perlin noise and cube renders, I moved on to the marching cubes algorithm. This is the outcome of polygonizng the voxels from the picture above. The mesh requires a long list of vertices and triangle ordering to correctly render it, as you can see here, the trangles that made up my mesh were very wrong. If I remember correctly, a combination of improper winding order along with incorrect edge vertex calculations (finding where along an edge between nodes that a vertex should be placed).

June 27 - 1:12am

This was the first run that generated a proper output along with a "soft edge" edge vertex calculation. I coined "soft edge" to represent when the vertex calculation uses interpolation based on the isovalues of the two vertices that the edge connects. A "hard edge" would just be using the midpoint between the nodes - this causes only flat or 45deg edges. Soft edges allow for really high resolution curves.

The noise generation is a 3D perlin noise function with a constant value for a floor

June 27 - 2:36pm

This is a test of my highest cube resolution. Cube resolution is what I used to define how many nodes are in a specific unity length. A low resolution has one cube per unity unit and an Insane resolution uses 8 cubes per unity length.

At high resolutions, the algorithm can create some really nice looking edges as shown here. I was really excited to see my idea for differing resolutions work so well - the extra time considering the calculations for various resolutions are well worth it after looking at the high resolution renders.

June 27 - 7:08 pm

After I was happy with the main components of the algorithm and noise generation, I set my sights on chunk based generation. This is the first cube render of a single chunk.

Since I didn't feel like the 3D noise generation was making a legitimate looking terrain, I turned to a 2D perlin noise function and extruded a heightmap from it. This process eliminated the soft edge feel since I couldn't figure out how to generate soft transitions with the isovalues, so I just used either a 0 or a 1 if it was above or below the height value from the heightmap. This 2D Perlin noise function is pretty much straight from Sebastian Lague's Procedural Landmass Generation series and the 3D function is strongly derived from it.

June 27 - 7:08 pm

First multichunk render. Clearly the noise generation is pretty messed up, but I had clear chunks and I was happy to move on for now.

June 28 - 4:45am

First attempt to add the marching cubes to the nodes. The noise issue is still present, but the bigger issue that I had was with the seems between the chunks.

June 28 - 3:37pm

With a little fix to the placement of the mesh creation with the chunk, I fixed the seems

June 28 - 3:57pm

Now that the seems are fixed, and the chunks are looking good, I worked on keeping the noise consistent between chunks. I realized that I had an issue with the offset and the scale of the noise. I wasn't considering the resolution of the cubes with the scale of the noise along with the offset.

June 28 - 4:57pm

Running the same project as above on my 3D noise generation. The seems between chunks were much more obvious than in the 2D generation, and I was extremely stumped on this for awhile.

June 28 - 6:48pm

Curbing the issue with the chunk seems, I began to work on the runtime manipulation of terrian. I used a raycast from the main camera where a left click would create an indent in the terrain and a right click would extrude it. However, the image here shows that no matter where in a chunk that I pressed, it only affected on a single line.

June 29 - 7:52pm

I realized that it was simply a positioning issue with my conversion from the raycast hit to the individual chunk's node.

June 29 - 12:36am

At this point, I began to work on the seems between the chunks and I realized that the issue was with the rounding of the noise function. Originally, I kept calling the noise generation function with a different offset each new chunk that was created - this lead to the rounding issue as the function iterated through more octaves from the perlin noise generator. To fix this, I created a massive 3D matrix of floats that were generated by the noise function and each index of the matrix would be associated with a node on the map. This way, there was no issue with rounding because the function was only called once.

June 29 - 12:39am

This is a test of the theory that the large noiseMatrix would help the terrain, the 3D noise generation showed the seems much clearer than the 2D and with this image, it was clearly fixed!

June 29 - 4:13am

Only issue is that when manipulating the terrain between chunks, the values were not lining up and I could not figure this one out for a while. This is just a picture of what the chunk boundaries look like when trying to manipulate a line between chunks.

June 30 - 4:13pm

I realized that the issue lied with the interpolation of the edge cubes. The interpolation was not considering any cubes on the edge and the sides of the chunks were not properly polygonizing. To fix this I needed to add some hidden node layers along all edges of the chunk so that the march through the cubes on the edge will properly interpolate and create proper edges.

June 30 - 7:55pm

At this point, I have properly generated multiple chunks, of varying resolution, along with run time manipulation of the terrain and created seemless transitions between chunks at generation and runtime during manipulation. I began to work a little on the 2D noise to create better terrains. It's not perfect, but for how little I understand about noise generation, I like the way that this turned out!

June 30 - 7:56pm

Now that the project is coming to an end, I decided to post the current progress on Reddit at /r/Unity3D and I got some amazing help from some of the people there regarding the efficiency of my code. Before adapting to their advice, the project ran at about 60fps when manipulating the terrain (250+ when not) but had very high stutters when manipulating the terrain. The stutters were a result of the garbage collector - something that I have never had to work with before, so this was a learning curve for me. Shout out to the devs on reddit for all the help in this department!

July 1 - (idk)

After consideration of all the advice from the redditors, I came close to the completion of my goal - An efficient Marching Cubes project with great amounts of comments and readability. T

July 3 - 1:00am

This is the profiler during constant terrain manipulation. This is a little more stuttery than I would like, but I am pretty happy with it in the end. There are no more lag spikes from the garbage collector and I learned a lot about the profiler as a result of this issue.

July 3 - 1:00am

This is just the profiler at idle.

July 3 - 2:30am

I really hated my 3D generation so I decided to create a sphere from the noise and use that as my "3D generation". I finally got to see the soft edge transitions between vertices again which was a nice sight lol.

July 4 - 1:50

This is just a massive sphere - if I remember right, there are about 110 million nodes in this image and there is no significant hit to fps at idle or during manipulation. The real issue is that at some points the rendering of the object is insane and will drop you down to crazy low fps if you don't have a beast of a rig.

Thank you for checking this project out! I had an awesome time working on the project and I really hope that it helps out those who come after me! Good luck!

#unity3d #unity #gamedev #procedural_generation #programming

unity

unity3d

gamedev

procedural_generation

Very cool.....but I have no idea what any of it means. I'm just glad people like you are out there.

6 years ago | Likes 2 Dislikes 0

Checkout the project! https://github.com/millerc3/Marching-Cubes

6 years ago | Likes 2 Dislikes 0