Sunday, November 13, 2016

c# - How to blend biomes with procedural terrain


I'm working on a terrain generator. Through multiple noise functions, I'm able to create many kinds of terrain I like, but I'm having a bit of difficulty joining them together in a seamless fashion.


My first thought was to use a single noise call (calling it the mask) and then I could simply say things like:


if (returnVal < .1) GenerateBiome1();
if (returnVal < .2) GenerateBiome2();
if (returnVal < .3) GenerateBiome3();

and so on...


The issue here is that the height of the terrain doesn't blend together when doing this. If biome 1 was more mountainous and biome 2 was flat land, it's a drastic switch from one to the other and it looks atrocious.


My next thought was to attempt blending by giving a 'strength' to each biome based on what my mask noise returns. In C# code, it looks something like this at the moment:



static public float GetHeight(float X, float Z)
{
float fRollingHills_Location = .25f, fRollingHills_Impact = .5f, fRollingHills = 0;
float fMountains_Location = .75f, fMountains_Impact = .5f, fMountains = 0;

float fMask = Game1.GetNoise2(0, X, Z, .01f);
float fRollingHills_Strength = (fRollingHills_Impact - Math.Abs(fMask - fRollingHills_Location)) / fRollingHills_Impact;
float fMountains_Strength = (fMountains_Impact - Math.Abs(fMask - fMountains_Location)) / fMountains_Impact;

if (fRollingHills_Strength > 0) fRollingHills = fRollingHills_Strength * (Game1.GetNoise2(0, X, Z, .02f) * 10f + 10f);

if (fMountains_Strength > 0) fMountains = fMountains_Strength * (Game1.GetNoise2(0, X, Z, .05f) * 25f + 10f);

return fRollingHills + fMountains;
}

The issue I have here is that even for only two biomes, it's pretty important for me to manually choose the "location" and "impact" values to ensure I'm getting some combination of strengths to total 100% by the time it returns a value (if not, I get things like giant cliffs making the borders from one biome to another ugly and obvious).


I don't know if I can give a good true question here other than, how should I actually be going about this? While I've managed a few good looking maps, I feel like I'm going about this in an overly complicated way that still doesn't give me all the customization I'm looking for.



Answer



3D Graphic with XNA Game Studio 4.0 has a chapter dedicated to this topic. It includes a complete process for generating the terrain and layering it with a variety of textures.


As luck would have it, that chapter is the sample provided by Packt on the book's page:




In this chapter, we will focus on building a full 3D environment. We will start by creating a class that builds a terrain from a 2D image called a heightmap . We will make a number of improvements to the basic version of this class, allowing multiple textures across its surface through multitexturing and extra detail at close distances to its surface through a "detail texture". We will look at a technique called region growing to add plants and trees to the terrain's surface, and fi nish by combining the terrain with our sky box, water, and billboarding effects to create a mountain scene..."



Sample chapter 7 pdf


Here's a summary of how they do it:


First, an image is used to generate a height map. Judging from the image, it looks like some sort of coherent noise function (Perlin noise, Simplex noise, value noise, etc) was used to generate the input image:


heightmap to terrain mesh


Next, they apply a technique they call multitexturing, which uses the red, green & blue channels of an input texture to draw additional textures onto the height map. In their example they use red for sand, blue for snow and green for rock. The remainder of the image is textured with a default such as grass:


enter image description hereenter image description here


At this point, the terrain looks okay at a distance, but if the camera gets too close the textures will blur. Increase the number of times the texture tiles will result in strobing where the high resolution texture flickers when scaled down & viewed at a distance. They solve these problems by applying a detail texture. The detail texture is essentially noise that is blended (multiplied in the pixel shader) to the terrain near the camera to fake the appearance of a higher resolution texture. Here's the noise texture they used:



enter image description here


Their final step is to add vegitation. Trees are added by randomly selecting locations & evaluating the slope. If the slope is too sttep, the site is rejected. Otherwise the location is used to add a tree billboard texture. Tufts of grass are added using a probablity map. Basically a random locations is selected & a random value is generated. If that random value is greater than the corresponding value in the probablity map, the site is reject. Otherwise a tuft of grass is added at that location.


enter image description hereenter image description here


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...