Adventures with Marching Cubes: Removing Duplicate Vertices

2025-03-03

Introduction

So you want to make some procedurally generated terrain? Easy enough to find code online for doing this cpu side with the marching cubes algorithm. But the cpu is slow and we want the Vertex Buffer to end up on the gpu memory in the end anyway for rendering. However compute shaders are highly parallel so we have to code around said restrictions. If you need an introduction to the basic principle of procedural terrain generation this is a good resource.

An example of what you could also use the marching cube algorithm I think might help understand what it actually does. Say you went for an MRI of you head and you had the full data, so you had the fun idea to 3d print your skull. If you were to input a density value between the density of your skull and the soft tissue then the marching cubes algorithm could output a list of triangles that we could load into a model file. We could then use the model file to 3D print your skull!

Overview of the Simpler Version of the Algorithm

Firstly we are going to go over the unidexed version of my implementation. Unindexed meaning a simple list of vertices where each three vertices is used to draw a triangle. A property of an unindexed draw is what we call flat shading. And in the above picture we can see that flat shading by the subtle lines(that are most visible in the terrain close to the camera).

There are three seperate compute shaders that generate the terrain.

  1. Generate a 3d texture representing the terrain.
  2. Create a 3d texture that allocates space in the vertex buffer.
  3. Create VertexBuffer from the 3d texture.

I would say that the first two steps are basically just prep. Step one randomly generates the terrain and stores it on the gpu. Step three is the meat and potatos of the marching cubes algorithm.