This is an old revision of the document!


Laboratorul 05. Biome Generator

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.

Fractal Noise

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:

  • Octava 1: forma generală a terenului (munți, văi)
  • Octava 2: detalii medii (dealuri, platouri)
  • Octava 3+: detalii fine (stânci, denivelări mici)

Parametrii care controlează fBm sunt:

  • Octave: Numărul de straturi de zgomot
  • Persistence: Cât de repede scade amplitudinea
  • Lacunarity: Cât de repede crește frecvența

Exponentul Hurst (H) se calculează din persistence: H = -log₂(persistence). El descrie rugozitatea suprafeței: H aproape de 1 ⇒ teren neted; H aproape de 0 ⇒ teren haotic. Dimensiunea fracțională a suprafeței generate este D = 3 − H.

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
}

Modelul Whittaker

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 -

Harta de elevație și harta de umiditate trebuie generate cu seed-uri diferite. Dacă se folosește același seed, cele două hărți vor fi identice, iar clasificarea biomilor va fi incorectă, deoarece fiecare punct va avea aceeași valoare de elevație și umiditate.

Implementare

  1. Fractal Noise
  2. Generarea celor două hărți de elevație și de umiditate, fiecare cu propriul seed
  3. Clasificarea biomurilor
  4. Construirea mesh-ului 3

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;

Tasks

  1. Generați harta de elevație și harta de umiditate cu seed-uri diferite, folosind în ambele cazuri multiple octave (6-8).
  2. Generați culori diferite pentru fiecare biom, folosind tabelul Whittaker.
  3. Construiți mesh-ul 3D atribuind fiecărui vertex înălțimea și culoarea corectă.
  4. Bonus 1. Implementați algoritmul Diamond Square, pentru a genera un heightmap.

  1. Inițializare. Se crează un grid de zerouri. Cele 4 colțuri sunt setate la o valoare aleatoare dintr-un interval predefinit de posibile înălțimi.
  2. Pasul Pătrat. Se calculează punctul din mijloc al fiecărui pătrat, făcând media aritmetică ale celor 4 colțuri la care se adaugă o valoare aleatoare dintr-un interval predefinit.
  3. Pasul Romb. Se calculează punctul din mijloc al fiecărui diamant, făcând media aritmetică ale celor 4 colțuri ale rombului la care se adună o valoare aleatoare din intervalul predefinit de valori aleatoare. În cazul în care rombul este incomplet, se iau în calcul doar colțurile existente în calculul mediei aritmetice.
  4. Recursivitate. Intervalul predefinit de valori aleatoare se înjumătățește. Se reiau pașii pătrat și romb până se aleg calculează toate valorile din grid.

Resurse: https://www.youtube.com/watch?v=4GuAV1PnurU

gp/laboratoare/05.1774634405.txt.gz · Last modified: 2026/03/27 20:00 by maria_anca.balutoiu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0