Search code examples
javaprocedural-generationweighted-average

How do i distribute the influence of different world generators to generate terrain?


My applogies for the title as I do not know the correct term for my problem.

I'm using Simplex Noise (with 8 octaves) to generate a height map for my terrain. To get the terrain blend in, I calculated which biome fits the location best using a temperature value and a rainfall value and got the squared value via:

Math.abs((biome.optimumTemperature-temp)*(biome.optimumTemperature-temp) + (biome.optimumRainfall-rain)*(biome.optimumRainfall-rain));

This value is then used to get the biome that affects the point the most (only 3 biomes are tested) i.e 1/(squared value) meaning the closer the ideal conditions are the more terrain control the biome has. But I don't know how to make the sum of Weights equal to 1.

Example 1:

Biome 0: FOREST Weight:0.04317983014648879  
Biome 1: MOUNTAINS Weight:0.9954832102244979  
Biome 2: PLAINS Weight:0.06793829435632236  

Here, the sum is: ≈1,10660133 which is greater than 1

Example 2:

FOREST Weight:0.01621210578957933  
MOUNTAINS Weight:0.023389024085188184  
PLAINS Weight:0.017797794332510785  

Here, the sum is: ≈0.0573989242 which is less than 1

To prevent an influence that approaches infinity if biome.optimumTemperature = temp and biome.optimumRainfall = rain meaning that later on it would become 1 / 0 (Bad) I have clamped the squared value to a maximum of 1 for each of the 3.

My question is how do I distribute the influence to all 3 biomes according to the conditions?

Note: it is okay for a biome to have an influence of 1 if it matches temp and rain perfectly but in that case the other 2 biomes should have an influence of 0.


Solution

  • It seems like you want to normalize the numbers. This is done by dividing each number by the total sum:

    double a, b, c;
    double sum = a + b + c;
    double normalizedA = a / sum;
    double normalizedB = b / sum;
    double normalizedC = c / sum;
    

    This ensures that the total sum of the new values becomes 1 (plus or minus any rounding errors from dealing with floating-point numbers) while retaining the relative sizes of the different numbers.