This is an old revision of the document!


Tema 3 - Worms 3D

  • Responsabili: Cristian Lambru
  • Lansare: 6 decembrie
  • Termen de predare: 12 ianuarie 2020, ora 23:55
  • Notă: Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!

În cadrul temei 2 trebuie să implementați un joc în care sunteți un aviator ce nu trebuie să se lovească de obstacole și nici să rămână fără combustibil pentru avion.

Construcția terenului

Harta de inălțimi

Definim o suprafață de baleiere descrisă de funcția:

$$ f(x,z) = y $$

Datorită construcției, o astfel de suprafață poate fi determinată direct de conținutul unei texturi în următorul mod:

$$ f(x,z) = texture2D(unitTexture,vec2 (u,v)).r $$

unde $\{u, v\}$ reprezintă coordonatele de textură asociate coordonatelor spațiale $\{x,z\}$.

Aceste tipuri de texturi, care descriu suprafețe de baleiere, se numesc hărți de inalțime sau height maps. Ele conțin în fiecare pixel o singură informație în $[0,255]$ (normalizată $[0,1]$), pe un singur canal, ce reprezintă înălțimea zonei acoperite de pixelul respectiv. Un exemplu de astfel de textură se poate vedea mai jos.

Geometria suport

Pentru a putea crea o suprafață definită de înălțimea dată de textură este necesară o geometrie suport care să cuprindă toate coordonatele $\{x,z\}$ finale. De asemenea, este necesar ca fiecărui vertex să i se asocieze o coordonată de textură, $\{u,v\} \in [0, 1]$, normalizată între limitele pe $x$ și pe $y$ ale geometriei suport.

Geometria suport se desenează cu un shader special, care la pasul de vertex shader accesează textura în care se află înălțimile. Prin interogarea texturii se obține înălțimea de la coordonatele $\{u,v\} \in [0,1]$, asociate vertexului. Această valoare se poate asocia direct coordonatei $y$ a vertexului sau se poate scala pentru un impact mai mare al terenului.

Calculul normalelor

Pentru a putea lumina terenul este necesară informația de normale. Tehnica pe care o vom folosi se numește “aproximare prin diferențe finite” și utilizează informația vecinilor pixelului din care s-a interogat înălțimea vertexului curent.

  • Se obține înălțimea de la poziția curentă, de la poziția din dreapta și de la cea de sus.

$$ height = texture2D(heightMap,vec2(u,v)).r \\ $$

$$ texelSize = vec2 (1.0/heightMapSize.x, 1.0/heightMapSize.y) \\ heightRight = texture2D(heightMap,vec2(u+texelSize.x,v)).r \\ heightUp = texture2D(heightMap,vec2(u,v+texelSize.y)).r $$

  • Se calculează diferențele pe $x$ și pe $z$.

$$ H_x = height - heightRight \\ H_z = height - heightUp \\ $$

  • Normala este reprezentată de vectorul unitate determinat de cele două diferențe finite pe $x$ și pe $z$.

$$ normal = normalize(vec3(H_x, 1, H_z)) $$

Deoarece diferențele dintre height și vecini pot fi destul de mici, este recomandat să folosiți un factor de scalare pentru $H_x$ și $H_z$.

Rezultatul după calcularea normalelor și adăugarea în scenă a unei lumini în centrul terenului:

Pentru adăugarea unei texturi de colorare a terenului (de exemplu pamant), se poate crea o coordonată de textură suplimentară doar pentru aceasta sau se pot folosi coordonatele de la harta de înălțimi cu o scalare. Rezultatul final în urma aplicării luminii și a texturii se poate observa mai jos.

Deformarea terenului

Buffer-ul hartii de inaltimi

Pentru a avea acces la buffer-ul de pixeli al imaginii este necesar să fie încărcată direct cu librăria stb_image. Această librărie se află deja în framework și cu ajutorul ei se poate încărca în memorie întreaga matrice de pixeli a unui fișier de tip imagine.

#include <stb/stb_image.h>
 
int width, height, chn;
heightPixels = stbi_load((textureLoc + "heightmap.png").c_str (), &width, &height, &chn, 0);
 
Texture2D* texture = new Texture2D();
glTexImage2D(targetType, 0, GL_RGB, width, height, 0, GL_R, GL_UNSIGNED_BYTE, (void*)img);
mapTextures["height"] = texture;

Buffer-ul heightPixels păstrează toată informația imaginii într-o zonă continuă de memorie în care prima dată se regăsește prima linie de pixeli (fiecare pixel are chn canale de culoare, bytes), urmată de a doua linie ș.a.m.d. Pentru a modifica textura, pur și simplu se modifică o zonă de pixeli din imagine, în interiorul acestui buffer și se reîncarcă buffer-ul în procesorul grafic.

texture->UploadNewData(heightPixels);

Framework-ul nu știe să incarce imagini cu un singur canal de culoare, astfel ca toate hartile de inaltimi trebuie sa contina rgb+a canale.

Notare (150p)

  • Construcția terenului (50p)
  • Deformarea terenului (50p)
  • Camera third person + lansare proiectil (20p)
  • Deplasare proiectil + camera observatie (20p)
  • Lumini spot deasupra celor doua personaje (10p)

Arhivarea proiectului

  • În mod normal arhiva trebuie să conțină toate resursele necesare compilării și rulării
  • Înainte de a face arhiva asigurați-vă că ați dat clean la proiect
    • Click dreapta pe proiect în Solution ExplorerClean Solution, sau
    • Ștergeți folderul /Visual Studio/obj
  • Ștergeți fișierul /Visual Studio/Framework_EGC.sdf (în caz că există)
  • Ștergeți fișierul /Visual Studio/Framework_EGC.VC.db (în caz că există)
  • Ștergeți folderul /.vs (în caz că există)
  • Ștergeți folderul /x64 sau /x86 (în caz că există)
    • Executabilul final este generat în folderul /x86 sau /x64 la finalul link-editării în funcție de arhitectura aleasă la compilare (32/64 biți)
  • În cazul în care arhiva tot depășește limita de 20MB (nu ar trebui), puteți să ștergeți și folderul /libs sau /Resources întrucât se pot adăuga la testare. Nu este recomandat să faceți acest lucru întrucât îngreunează mult testarea în cazul în care versiunea curentă a bibliotecilor/resurselor diferă de versiunea utilizată la momentul scrierii temei.

egc/teme/2019/10.1575502121.txt.gz · Last modified: 2019/12/05 01:28 by andrei.lambru
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