Hi, I’m a self taught programmer and highschooler who’s been working on a project for a bit now and iv’e been stuck on something for a while, i want to generate smooth voxel terrain, but so far I could only make “minecrafty” blocky style terrain. iv’e done research on marching cubes and things like that but i just cant figure out how use it, i’m using a multidimensional array to place the cube voxels. now i need to figure out how to create smooth terrain out of it, then hopefully i can make a way to add and delete terrain from there. Any help would be amazing.
Marching Cubes is one of the simplest algorithms out there (actually it’s simpler than even the face-testing minecraft-style system), but it trips a lot of people up because what you are doing is looping through corners, not blocks, and additionally there can be the concept of signed distance, which helps smooth out your terrain.
The basic idea is this:
-Each of your voxels has a distance value. 0 means it’s on the surface of your terrain, negative means inside, positive means outside. Odds are, most of the points on your voxel grid will not be exactly 0.
-Instead of looping through the voxels themselves, imagine a grid that’s offset by half a voxel, so each cell has 8 voxels, one for each corner.
-Each corner can either be inside (or on) or outside the terrain. The real surface of the terrain is somewhere in that cell, at the point where the density in between the voxels is 0.
-Each corner also has a value. These values are powers of two, so you have a corner for 1,2,4,8,16,32,64, and 128.
-If a corner is inside/on (negative/0) the surface, that value gets added. If it’s outside (positive), it doesn’t. Since each corner can only be either inside or outside, this is binary. There are 8 corners, so that’s a byte. You might have a cell where the corners are OOOOIOII (O for outside, I for inside). This can be represented as 00001011 in binary, or the decimal number 11.
-As you can probably see, there are 256 possible cell types. Each one corresponds to a specific surface. For instance, 0 and 255 are empty, since they are completely outside or completely inside, but 1 has a single triangle.
-All of these surfaces are based on trying to find a surface that has a vertex for each edge where one side is inside and one side is outside. This table can be precomputed or hardcoded. This is the longest part of making marching cubes, but it isn’t hard. There are also existing tables already that you can adapt.
-Loop through your array, taking 2x2x2 voxel sections and treating them as cells. Find the byte value of the cell based on which voxels are inside and which are out.
-This byte value is the index to the array you precomputed earlier. Use it to get the mesh data (if any) that you should add to the chunk’s mesh.
-For real smoothness, move the vertices along their edges corresponding to the distance of the voxels at the corners. A vertex between a -0.25 and 0.75, for instance, would be placed 0.25m away from the inside voxel (and 0.75 away from the outside one).
Also, I’m almost certain you’ve seen This paper, but it’s a really good description of how it works. This video is a great visual example as well, and you could probably get an idea of how to make this just by watching it enough times.
I’m also a self-taught coder who started in elementary school so I get the feeling of wanting to make stuff like this but having getting really stuck at the implementation. So much of the literature has a higher barrier to understanding than it reasonably should.
Anyways, I wish you the best of luck on this project! Voxels are a whole lot of fun…
(Also, once you get this concept down in C#, check out this awesome magical spell that can work with voxels (and other stuff) really fast.
Hello @Zarenityx ,
What s the way to go for having voxel with values between -1 and 1.
Why do we must loop with 2x2x2 voxels grid?
thx