Using the plain Marching Cubes algorithm produces a pretty dull and uniform-looking terrain. For “regular” modeling purposes this is fine since the mesh is assigned proper vertex normals, so that the shader can shade it “realistically”. However, since I’m still bent on using flat shading and I hate “realism”, the terrain I get is boring as hell. So, I decided to deform it a little bit.
I was researching the best way to encode distortion into the marching cubes algorithm, and started fiddling around with 3D Perlin noise. I thought I could generate three 3D noise functions (one for each coordinate), and then make a vector out of those that would represent the distortion vector at that given point. However, since the algorithm for generating seamless 3D noise was a bit more complicated than I thought necessary, after some more poking around I thought “how about instead of 3D noise I use a set of vectors in space, and then when calculating the distortion vector at a given point, I interpolate the nearest neighbour vectors?”. Google pointed me right at vector fields. Perfect!
The code for calculating the interpolated vector at a given point inside the vector field is quite simple. Since the vector field internally uses a 3D array of Vector3 objects, in order to calculate the interpolated vector at a given point, we have to sample all eight vectors that are defined on the vertices of the imaginary cube encompassing the given point. Since the given point is closer to some vectors than others, we need to scale the “influence” each vector has on the resulting vector based on its distance from the given point. Here’s the code if you’re interested.
Here’s how a 4x4x4 vector field looks when interpolated using 20 samples along each axis:
Sweet. Now let’s put that to use. Now that I have the distortion vector at any coordinate I want, I can use it to offset the “boring” lattice coordinates that Marching Cubes gives us, and create terrain that looks more dynamic.
After plugging that into the terrain generator, here’s what I got:
Pretty sweet looking terrain, compared to the boring-ass stuff I had earlier. There’s still some issues with “ribbed” polygons, which you can see on the left side of the fourth screenshot. Don’t know where that’s coming from, will investigate.
Another nice property of the distortion is that now the LOD boundaries are less apparent. You can try finding the LOD boundaries on the screenshots above, but here’s a wireframed version showing how it really looks like:
The closer you are though, the harder it is to see the boundary.Since the player is looking at all this from an even more up-close point, and he doesn’t have the wireframe helping him, the boundary is pretty well hidden.
I’m rather pleased with how this came out. The next steps regarding distortion are to figure out a way to distort the distortion field! Seriously. I’d like the vector field’s vectors to not be evenly spaced across the field, but to be somehow more grouped together semi-randomly. That way I could have regions of greater detail (more “curvy”), and regions of more uniform looking terrain, which would benefit the visual diversity. As you can see, right now everything is kind of equally distorted, and I’d like to change that. Ideally, there’d be a way to control this “distortion distortion” through some user-facing editor params.