This is usually a result of whatever fractal or noise based function that is used to generate the heights being applied in too uniform a fashion over the whole landscape area, it's also a result of the fact that most of these functions treat 3D space as a uniform entity so there is no sense of direction and no knowledge of the processes of fault formation and erosion that shape real landscapes.
The image here taken from Geo shows clearly what I mean - a fairly constant lumpiness that isn't exactly convincing:
Now matters can be improved somewhat by using more noise functions at lower frequencies to control the parameters but you still end up with no directionality and something that while less regular is still far from realistic. This second image is taken from Google Earth and shows the sort of ridges and valleys that I am after but so far lacking:
There are several research papers out there I've found so far that present various techniques for producing more physically accurate simulations of terrain based upon studies of real geological formations, wind and water erosion and other climactic factors, but these are invariably very complex, very slow or only model a certain effect in isolation - I really want to develop something that runs while not in real time at least in seconds or minutes rather than hours and I need to understand it completely so I can alter and tweak it to get the effect I want.
Not being a mathematical genius I find many research papers quite impenetrable but what most annoys me is when they are deliberately so - simple coding concepts expressed in complex algebraic formulas for example when half a dozen lines of pseudo-code would make it blindingly obvious to anyone with even rudimentary coding ability. I'm not anti-academia, and I'm certainly not anti-research; I just want people to express their ideas in a form that will *help* others understand and develop them rather than in a form that is apparently designed just to make them look as clever as possible.
Okay, with that personal rant over - being unwilling to get into the complexities of real geological simulation what I thought I would do therefore is have a bit of a go at trying to create something that was closer to real world mountains and valleys but was still controllable with just a couple of parameters. It also had to be quite efficient to generate and combine well with other procedural techniques I may employ.
The plan I came up with was to try to 'grow' a set of line segments representing the mountain ridges I wanted then calculate the height of the terrain as a function of the distance of each point from one of these ridges. The ridge line segments are 2D and so can be easily visualized by rendering them to a bitmap but are mapped onto the surface of the planet using a simple transformation.
Shown here is one of the first implementations of this system, it starts with a single point located roughly at the centre from which three ridges head out in randomly chosen directions - although the directions are chosen to not be too close to each other. Each ridge is formed from a number of consecutive segments with a random orientation change applied before each one is added making the ridge meander around in a more convincing fashion. The segments also get progressively lower in altitude and there is a random chance at each step that the ridge will fork into two with each child ridge heading off in a random direction based off the direction of the original.
From this I then had a look at working out height values based on the distance of each point from the closest ridge, the results are shown here both as a grayscale of the height field and as it appears when applied to a planet surface
It was quite an encouraging result and made me feel I was on the right path at least to produce the kind of effect I wanted, but there was obviously much more to be done. The first improvement was to do something about the function that works out the height of a terrain point from it's distance to the nearest ridge line segment. The image above was generated using a fixed linear distance function but this doesn't make much sense really as the 'tail' end of the segments are much lower in altitude than the roots and so should have a lower influence. Taking this into account by scaling the distance over which a segment has an influence based upon it's height gives a better result:
Now a single mountain does not a range make, so next I tried generating ridges from multiple points combining the results by taking the highest point at each intersection:
Which looks a bit better, and while as many points as required could be combined in this way, I thought it might be nice to be able to generate ridge line segments all starting off from a connected 'master ridge' rather than discrete points. This master ridge formation is controlled by specifying a number of spawn points just like for the images above, but this time rather than treating them independently, the program creates a sequence of connected segments directly between the spawn points:
It's pretty uninteresting with straight lines between the points, but we can make it more interesting by subdividing these connecting segments into smaller pieces and displacing the newly created intermediate points by some sort of random function. The method I chose is very simple and something of a fractal classic:
1. take each straight segment shown above and split it at it's middle point into two
2. displace the newly created middle point by a random distance in a direction perpendicular to the original line
3. repeat this process recursively on the two new half-length segments as long as they are longer than some minimum threshold.
What we now get is something a lot more interesting and closer to what we might expect from a mountain ridge line:
Of course we don't want just one big ridge, so by adding in the spawning of child ridges from the sides of our master ridge we get something a bit more like what we were after at the beginning, a combination of ridges in various directions and sizes but all heading down from our master ridge. These child ridges are set to spawn randomly along the length of the master ridge but head out in a direction roughly perpendicular to the direction of travel of the master ridge at their spawn point so they generally fan out from ridge in a fairly sensible pattern:
Looking at this effect now I reckon it would be even better to spawn some additional children from the end points of the master ridge to get rid of the 'bulb' of height influence around those points...something to try I think.
One thing obvious from these images however is the way the land on either side of the ridges slopes away at a constant slope producing a hard edge along the ridge itself and an unrealistically constant gradient on either side. To solve this my next step was to exchange the linear distance function used up to this point for a hermite interpolation that provides a smoother blend between the points at the ridge top and those at the bottom of the slope. The difference can be clearly seen on these two simple graphs:
You can see the smooth-step graph on the right hand side forms a far more natural shape for the hillsides and because the slope becomes more gradual towards the top (the right hand edge of the graph) the ridge line itself is wider, smoother and far less like a knife edge.
Finally to make things a bit more interesting again let's add some higher frequency perturbations using a ridged fractal similar to that from our original homogenous landscape but at a much lower amplitude just to add variety over our too-smooth slopes:
This is finally starting to look a bit more like some mountains although there is fairly obviously still a very long way to go to achieve something that really does look realistic - there are some undesirable artifacts where ridge influences meet for example producing fairly artificial looking gulleys, but it's certainly promising enough I think to continue the experiment.
PS: Hope you found this interesting, it certainly helps me get my head around the process documenting it in this much detail - constructive feedback and comments are as always welcomed!