I have a very simple procedurally-generated planet renderer:
- Each patch of terrain is a quad patch at a fixed tesselation level (such as 33x33 vertices).
- Patches are arranged in a quadtree; when the average size of a quad in a patch takes up too many pixels, the patch is split into 4 smaller patches; likewise when polygons get too small, a patch and it's siblings are removed and the parent node is put back into the renderlist.
- The root-level of the quadtree is simply a 6-faced cube, each face is one of these patches that has been deformed to fit on a sphere
- Yes, at the root-level the points are not evenly distributed; a common problem when squishing a cube into a sphere. but as you get closer, certain areas will split before others, and it's not long before things even out. I don't really care that things are a little uneven when zoomed out; its much less annoying than dealing with polar coordinates!
This is what works:
- Plain sphere: When it's time to split a patch, I generate a more-detailed patch. In the simple case of a sphere with no added detail, I compute the points on the sphere exactly for the new patches. This works fine, I get a perfect sphere I can zoom into all I want.
- Bilinear filtering: Instead of computing the points from the sphere, I cut the patch into 4 subpatches (so 33x33 becomes 4x (17x17), and then I up-scale the 17x17 patches to 33x33 be linearly interpolating the in-between vertices.). This works fine when detailing the sphere; the sphere does not become smooth (because it started as a polygonal model), but it does result in becoming more tesselated.
- Bilinear filtering with random detail: Same as above, I add a random bit of vertical (relative to the center of the sphere) displacement to the interpolated vertices. This results in rocky terrain the gets more and more detailed as you get closer to it. This is what I want. Each successive generation, I pass down a lower 'detail scale' value, so that the smaller I get, the smaller the random displacement details are. So each generation, I divide the detail height value by 2. This seems to scale properly. I don't have any problems with this.
The problem with #3 above, is that the terrain is little more than a heightfield. It can become more detailed, but each point on the sphere has no other points above it. It's kind of 'standard.' I wanted to go a step further than what all the other terrain generators do. So, instead of displacing a random height in the direction away from the center of the sphere, I displace along the point's normal vector. The result is more realistic; sometimes detail will cut into the side of a cliff. It gives the surface some undercuts. Sometimes the undercuts have undercuts. If you move the camera into these undercut areas, some places are almost like mini-caves. For the most part, it looks pretty cool.
The problem I am having, is now that I have given the surface this 'extra' degree of freedom it never had before, there are some areas where the terrain will intersect itself. In the case of a cave-like area, its fine, I dont care, the ceiling is touching the floor or something; it's a place where the player can't go past. The barrier doesn't look bad. But it leads to weirdness at the tops of mountains where instead of coming to a point, imagine there's a column and both sides are undercutting into it enough that they sort of pinch past each other, leaving the top part of the column connected to the the bottom by an infinitely thin piece of rock; something completely impossible. Is there any way to prevent, hide or mitigate this?
I can post images later tonight probably.