I've recently picked up procedural generation and it's been going great - until I decided to give Biomes a shot. With my current setup, I can assign a specific point in my world a biome based on its current height in a "global" biome noise generated with Simplex. The issue i'm having (and many others it seems) is to blend these biomes with eachother - while still being able to decide what goes where.

I tried blending it on my own by simply generating a height with a weight-value that could help with blending a biome with its neighbor. I calculated the weight by getting the distance normalized in a 0 to 1 scale, using this as a percentage. So if the "heaviest" biome had a weight of 0.8, the other neighboring biome would then have 0.2.

float totalHeight = (mainBiome * weight) + (otherBiome * (1f - weight));

However this didn't work out as I still got cliff-like borders between different height biomes.

Then I found an algorithm at Parzivail.com that actually worked perfectly in blending a biome with its surrounding biomes. The only issue is that it's pretty much only based on the index of my biomes-array.

float totalHeight = 0.0f;
float n = biomes.Length;
for (int i = 0; i < n; i++)
    float left = (i - 1f) / (n - 1);
    float right = (i + 1f) / (n - 1);
    if (left < noiseHeight && noiseHeight < right)
        var layer = biomes[i];
        float w = -Mathf.Abs((n - 1) * noiseHeight - i) + 1f;

        layer.Evaluate(x, y, sampleCenter);

        totalHeight += w * layer.Height;
        layer.Weight = w;

(desmos.com visualization)

I've tried modifying it in order to determine biomes based on temperaute and not only height, but whatever I do seems to bring the cliffs back.

Current implementation with seamless transition Current implementation with seamless transition

How would I change my way of doing this, so I could set up the placement of biomes in a better way and not be forced to use my array indexes?

  • 1
    \$\begingroup\$ We have quite a lot of past Q&A covering different approaches for blending biomes — can you show us how you've tried applying these existing answers and where they're not serving your needs? \$\endgroup\$
    – DMGregory
    Commented Jun 30, 2021 at 22:38
  • \$\begingroup\$ @DMGregory Actually managed to get it to work. Should've kept scrolling down further on one of the questions in your link, as there was a great explanation on how to do it. I'll post an answer with how I solved it below. \$\endgroup\$ Commented Jul 1, 2021 at 8:16

1 Answer 1


So, after carefully reading the post at https://gamedev.stackexchange.com/a/164252/85899 I managed to get it to work as I wanted it. I'm currently in the works of adding temperature/moisture levels aswell, but I feel like it won't be an issue with this implementation. I'll share my solution below:

float noiseHeight = BiomeNoise.GetHeight(x, y, sampleCenter); // returning a noise value between 0 and 1
float totalHeight = 0.0f;
float totalWeight = 0.0f;
int n = biomes.Length;
float[] weights = new float[n];
// Evaluate the point (x, y) with each biome
for(int i = 0; i < n; i++)
    var layer = new BiomeLayer() { Biome = biomes[i] };

    // Calculates the noise for a specific point with a given biome
    layer.Evaluate(x, y, sampleCenter);

    float weight = (layer.Biome.Influence - Mathf.Abs(noiseHeight - layer.Biome.StartHeight)) / layer.Biome.Influence;
    // As we don't care about weights below 0, we can just skip blending this biome by setting a weight to 0
    weights[i] = Mathf.Max(weight, 0);
    layer.Weight = weights[i];
    totalWeight += weights[i];  

    float height = layer.Height * weights[i];
    totalHeight += height;

// Divide total height by the sum of all weights
totalHeight /= totalWeight;

Result: (Canyons with a mix of grasslands at bottom left, desert at top right) - the pixelation is due to the LOD system. It's perfectly smooth at the biome borders! enter image description here


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .