This is an old revision of the document!
Generarea procedurală de biomuri este o tehnică utilizată pentru a crea lumi virtuale cu zone cu proprietăți geografice distincte (ocean, deșert, junglă, tundră etc.). Fiecare biom este caracterizat de condiții climatice specifice, vegetație și relief. Astfel, în acest laborator se va implementa un sistem simplificat de generare de biomuri pornind de la două hărți de zgomot și clasificarea acestora pe baza modelului Whittaker.
Pentru a îmbunătăți realismul terenului generat, tereneul se poate genera folosind fractal noise, care combină mai multe straturi (octave) de zgomot Perlin la frecvențe și amplitudini diferite. Fiecare nouă octavă introdusă adaugă un nivel de detaliu:
Parametrii care controlează fBm sunt:
float FractalNoise(int x, int y)
{
for (i = 0; i < octaves; i++)
{
xCoord = (float)x / width * scale * frequency;
yCoord = (float)y / height * scale * frequency;
perlinValue = Mathf.PerlinNoise(xCoord, yCoord) * 2 - 1;
noiseHeight += perlinValue * amplitude;
amplitude *= persistence;
frequency *= lacunarity;
}
return (noiseHeight + 1) / 2; // Normalize to 0 - 1
}
Pentru a clasifica biomurile se poate folosi modelul Whittaker, care folosește două axe climatice pentru a defini zonele geografice: temperatura (corelată cu elevația) și nivelul de precipitații (corelat cu umiditatea).
Un tabel simplificat de clasificare Whittaker poate fi următorul:
| Biom | Elevație | Umiditate |
|---|---|---|
| Ocean | < 0.35 | - |
| Plajă | 0.35 - 0.40 | - |
| Deșert | 0.40 - 0.75 | < 0.20 |
| Savană | 0.40 - 0.75 | 0.20 - 0.40 |
| Pădure temperată | 0.40 - 0.75 | 0.40 - 0.65 |
| Junglă | 0.40 - 0.75 | 0.65 - 0.85 |
| Mlaștină | 0.40 - 0.75 | > 0.85 |
| Tundră | 0.60 - 0.75 | < 0.40 |
| Taiga | 0.60 - 0.75 | > 0.40 |
| Zăpadă / Munte înalt | > 0.75 | - |
Pentru fiecare vertex al grilei se calculează înălțimea din harta de elevație și culoarea din clasificarea biomurilor. Apa este aplatizată la waterLevel pentru a simula suprafața oceanului:
for (int z = 0; z < mapHeight; z++) { for (int x = 0; x < mapWidth; x++) { int idx = z * mapWidth + x; float height = elevationMap[x, z] < waterLevel ? waterLevel : elevationMap[x, z]; vertices[idx] = new Vector3(x * meshScale, height, z * meshScale); colors[idx] = GetBiomeColor(elevationMap[x, z], moistureMap[x, z]); } }
Triangularea grilei (două triunghiuri per pătrat):
int a = z * mapWidth + x; int b = a + 1; int c = a + mapWidth; int d = c + 1; triangles[triIdx++] = a; triangles[triIdx++] = c; triangles[triIdx++] = b; triangles[triIdx++] = b; triangles[triIdx++] = c; triangles[triIdx++] = d;
Diamond Square, pentru a genera un heightmap.