This is the last step for this first phase of the project. By using the elevation, temperature and rainfall maps the biome map can be generated. This is a really simple process as it just involves matching ranges to specific biomes. The first step is to split the input maps into discrete levels:
- Continental Shelf
- Flat Lands
- Hills (“Non-Rocky” rises)
- Low Mountains (“Rocky”, Peaks below tree line)
- Medium Mountains (“Rocky”, Peaks above tree line)
- High Mountains (“Rocky”, Peaks far above tree line)
Once the maps have been split up into discrete components it is simply a matter of matching them to the biomes based on a set of rules. In the gallery the first image is temperature, then rain/humidity and then the resulting biome.
Notes: In the original temperature generator I used the elevation to reduce the temperature. This proved to be unnecessary as it is just easier to prefix the biome with mountain or hill to specialize it to the elevation. Elevation is not taken directly into account to generate these biome maps. Hill and Mountain are used as modifiers to the biome map.
I finally managed to play with the rain shadow and combining it with some noise maps enough to be (somewhat) happy with the rainfall maps that it is generating. I ended up rewriting the the temperature, wind direction, and rain fall map generators to all use the same abstract base class which generates a series of horizontal bands into a gradient. The base class then calls an abstract method to allow different noise implementations to be applied to the gradient. The method used is still the same as explained in the post for the wind direction map it is just more flexible now.
The rain fall generator works in the same way as the wind direction generator. In this case different bands are defined to create dry and wet bands which are then distorted by a noise map. The result is then biased by the rain shadow map to make it dryer in areas of rain shadow. Here are some of the results:
- Grey = Arid
- Dark Red = Semi-Arid
- Yellow = Moderate
- Light Green = Semi-Wet
- Dark Green = Wet
I managed to speed up the rain shadow generation but it is still pretty slow. I am going to leave it for now since I have run out of ideas to make it faster for now. Next up is biomes.
Originally my plan was to combine the wind speed and wind direction maps to form vectors where the wind speed was the magnitude and the wind direction was the angle and then trace those over the elevation to create the rain shadow. The results were not very good so I discarded the wind speed maps (I wasn’t too sure about their accuracy anyways) and am now using a constant vector magnitude instead.
Here is a description of the process:
- Initialize a 2d array to 1.0 to serve as our rain source.
- Repeat the following for the number of iterations:
- For each cell do the following:
- If the rain source is 0.0 continue to the next cell, otherwise:
- Project a series of rays to form a circular arc. Rays are projected from wind direction angle – PI/8 -> wind direction angle + PI/8.
- Each ray is drawn using Bresenham’s line algorithm.
- As the ray is projected the value being added to the resulting map is decayed by a set percentage.
- As the ray is projected the elevation is evaluated, the ray continues to trace until it reaches the end or it climbs past the elevation threshold and reaches a local maximum.
- Take the resulting map and any points that are below a threshold set the corresponding point in the rain source to 0.0.
Next I need to create the rain fall maps and combine them with the rain shadow to get the final rain maps.
- Black = Rain Shadowed
- White = Normal
Today I finished the code for generating wind speed and temperatures.
The wind speed defines bands above and below the equator where the wind speed is high while it is lower at the equator. These bands are combined with the land mask to make the wind higher over the ocean and weaker over land. Steps:
- Start with a base noise map. (FBM octaves = 5.0 and size = 4.0)
- Define bands where with varying wind values. (Strong-Weak-Strong for this example)
- For each cell the value from the band is added to the noise map multiplied by the base noise weight.
- To complete the base map the whole map is normalized between 0.0 and a base weight.
- A second noise map is created called the continent noise map. (FBM octaves = 5.0 and size = 8.0)
- Using the Voronoi operation create a map where every cell has a value equal to its distance to the nearest coast.
- For each cell I create a weight based on the distance to the coast. If the point is further than the distance threshold the weight is 1.0 if over ocean and 0.0 if over land.
- This weight is combines the the continent weight and then multiplied by the continent noise and added to the base map.
- The final map is then normalized.
The temperature map is a simple linear gradient biased by the elevation and a bit of noise to make it more interesting. Steps:
- Each row base value is equal to lerp between 0.0 and 1.0 where the poles are 0.0 and the equator is 1.0.
- For each cell in the row distort the row value by the matching cell from a noise map multiplied by the distortion factor. (In this example FBM was used octaves = 5.0 and size = 4.0)
- If the elevation for the cell is greater than a set threshold I decrease the temperature based on where the elevation lies between the threshold and the max elevation.
Next Steps: Rainfall & Rain Shadow
Wind Speed Legend:
- Black = Low Wind Speed
- White = High Wind Speed
- Red = Hot
- Green = Moderate
- Blue = Cold