Procedural generation of a constrained landscape

前端 未结 1 591
栀梦
栀梦 2021-02-02 03:55

I\'d like to implement a procedural generation of a terrain. After a thorough research I came up with a conclusion that it should be implemented with one of the gradient (cohere

相关标签:
1条回答
  • 2021-02-02 04:47

    How can I improve the Perlin Noise algorithm, so that along this curve the noise will have a preferred range of values (or, for simplicity, value 0)?

    This can be achieved by transforming each pixel in the map through a simple p -> f(p) mathematical function.

    Consider a function, which maps the purple line into the blue curve - it emphasizes lower located heights as well as very high located heights, but makes the transition between them steeper (this example is just a cosine function, making the curve less smooth would make the transformation more prominent).

    Cosine value transform

    You could also only use bottom half of the curve, making peaks sharper and lower located areas flatter (thus more playable).

    Cosine value transform II

    "sharpness" of the curve can be easily modulated with power (making the effect much more dramatic) or square root (decreasing the effect).

    enter image description here

    Implementation of this is actually extremely simple (especially if you use the cosine function) - just apply the function on each pixel in the map. If the function isn't so mathematically trivial, lookup tables work just fine (with cubic interpolation between the table values, linear interpolation creates artifacts).

    (Copied from my aswer to another question)

    If all you need is to transform the generated noise into a known value range (like -1.0 - 1.0), use this algorithm:

    function scaleValuesTo(heightMap, newMin, newMax)
    {
        var min = min(heightMap);
        var range = max(heightMap) - min;
        var newRange = newMax - newMin;
    
        for each coordinate x, y do:
            hrightMap[x, y] = newMin + (heightMap[x, y] - min) * newRange / range;
        end for
    }
    

    I'd like to apply some constraints (like where should be a mountain range, or where should be a lowland etc.).

    This is a bit more complicated, because you need to specify where the mountains will be. The easiest solution is to create a separate height map (you can do this either procedurally or load it from a bit map, it doesn't matter) with the rough shape of the terrain desired and then add it together with your noise map. There are a few things to keep in mind:

    1) Make sure there are no sharp edges on the template map (those would be very visible on the combined map). Box blur is usually enough for this purpose, although a more complex filter like Gaussian blur gives better results (in some occasions, box blur will preserve some sharp edges on the map).

    2) You may want to give higher priority to the noise map in higher elevations and lower priority in lower elevations. This can be easily achieved by doing something like this: combinedMap[x, y] = templateMap[x, y] + (0.2 + 0.8 * templateMap[x, y]) * noiseMap[x, y].

    You can see this approach on this diagram:

    http://matejz.wz.cz/scheme.jpg

    (I have made this for my own terrain generation project)

    0 讨论(0)
提交回复
热议问题