Tema 1

  • Responsabili: Anca Băluțoiu, Silviu Stăncioiu, Mihnea Mitrache, Andrei Voicu
  • Lansare: 15 noiembrie 2024
  • Termen de predare: 11 decembrie 2024, ora 23:55
  • Notă: Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!

În cadrul acestei teme va trebui să realizați o simulare a unui lac de la munte, în care se varsă o cascadă. Simularea se va face pe timp de noapte, în scenă fiind prezente surse de lumină dinamice. Un video demonstrativ ce înfățișează o posibilă implementare îl puteți viziona în filmulețul de mai jos:

Teren

Se va genera procedural un mesh pentru teren. Pentru a simplifica lucrurile, mesh-ul va fi generat în întregime pe CPU (folosind metoda prezentată în laboratorul 2 de EGC), nefiind necesară folosirea de Geomtry Shaders. Inițial se va porni de la un grid de rezoluție m x n, iar apoi se vor face următoarele operații de displacement pe vertecșii acestuia:

  1. Definirea suprafețelor concave și convexe ale terenului: Terenul va defini o suprafață convexă pentru zona în care se va afla lacul și una concavă unde vor fi munții. Displacement-ul aferent acestor parabole va fi calculat în funcție de distanța dintre vertecși și centrul mesh-ului astfel:

unde hmax este înălțimea dorită pentru suprafață, iar d este o valoare calculată în felul următor: unde v este poziția vertexului curent în planul XZ, c este centrul mesh-ului în planul XZ, iar r este raza gropii. Rezultatul dorit este următorul (imaginea afișează normalele suprafeței pentru a fi mai ușor de perceput forma):

  1. Denivelări ale suprafeței pentru a da impresia de munți: Pentru asta se poate folosi noise: The Book of Shaders: Noise. După aplicarea denivelarilor, un rezultat satisfăcător este acesta:
  2. Curbură ce definește zona prin care se va vărsa cascada: Se va folosi o curbă Bezier pe baza căreia se va denivela o parte a terenului. Pentru fiecare pereche (xv, zv) de coordonate ale vertecșilor terenului în planul XZ și fiecare pereche (xc, zc) de coordonate ale curbei Bezier în planul XZ se va calcula parametrul t al curbei Bezier pentru care distanța dintre (xv, zv) și curba proiectată este minimă.

Pentru a găsi cel mai apropiat punct pe o curbă Bezier în 2D, cea mai ușoară soluție este să iterăm cu pași mici pe curbă, evaluând curba în câte două poziții care formează un segment, iar apoi să calculăm matematic cel mai apropiat punct pe fiecare segment.

De asemenea, pe lângă parametrul t, ne interesează și distanța d_bezier dintre vertexul nostru proiectat pe XZ și punctul găsit anterior.

Parametrul t este apoi folosit pentru a evalua curba propriu-zisă (nu cea proiectată pe OZ) și a găsi cel mai apropiat punct de pe curbă. O să numim acest punct b_closest.

Pentru a realiza curbura în teren putem interpola între înălțimea sa inițială și înălțimea celui mai apropiat punct pe curba în 3D (y_b_closest) astfel: unde r_cascada este raza cascadei noastre.

Folosind formula descrisă mai sus vom avea o curbură, dar aceasta nu va avea o formă naturală. Putem îmbunătăți forma acesteia folosind funcția sinus:

Un rezultat al acestei operații poate arăta în felul următor:

După toate aceste operații, forma terenului este gata, dar mai trebuie calculate normalele pentru a se putea implementa iluminare. După ce avem mesh-ul, putem calcula cu ușurință normalele prin calcularea vectorilor de direcție dintre vertecși adiacenți pe axele X și Z, iar apoi realizarea produsului vectorial dintre acești vectori și normalizarea rezultatului.

Pentru extremitățile mesh-ului este posibil să nu avem vecini ai vertecșilor în fiecare direcție. În cazul în care vertecșii nu au vecini pe anumite direcții, se vor folosi doar vecinii pe care îi au pentru a calcula vectorii de direcție.

Lumini

În aplicație vor exista mai multe lumini sferice de culori diferite care se vor mișca în scenă. Animațiile acestora nu trebuie să fie complexe, puteți folosi transformări simple precum rotații și translații.

Pentru a începe implementarea puteți folosi laboratorul despre deferred rendering ca punct de plecare.

Cerul

În implementarea temei trebuie să sintetizați atât cerul cât și pereții exteriori ai mediului înconjurător. Veți folosi un cubemap sugestiv pentru a realiza această sarcină. Varianta folosită în temă este disponibilă aici.

Lacul și Reflexiile

Pentru a reprezenta lacul vom folosi un model de plan. Acesta poate fi încărcat fie din modelele puse la dispoziție de framework, fie generat procedural (ca mesh, sau din geometry shader, etc).

După cum știm, în realitate mediul înconjurător se reflectă pe suprafața apei. Acest efect trebuie implementat și în cadrul temei. O reflexie corectă a mediului înconjurător pe suprafața apei presupune surprinderea tuturor elementelor care se regăsesc deasupra apei (cerul, munții, etc.) și reflectarea acestora pe suprafața sa.

Ne putem raporta la modalitatea în care am implementat reflexia mediului în cadrul laboratorului despre reflexii.

Maparea mediului se realizată din centrul scenei, pe direcțiile prezentate în diagramă.

Dacă dorim să se păstreze și iluminarea în reflexia calculată, atunci va trebui modificat modul de randare a mediului în cubemap. Pentru a face asta, este nevoie de deferred rendering la nivel de cube map, cu shader speciale pentru asta (shader care sa scrie informațiile despre scenă și shader pentru light accumulation).

Procesul este similar cel folosit în laboratoarele despre reflexie și deferred rendering, cu excepția câtorva observații:

  1. Trebuie implementată abilitatea de a defini frame buffere care conțin mai multe texturi de tip cube map. Această funcționalitate se implementează similar cu adăugarea mai multor texturi normale unui frame buffer.
  2. Texturile din cadrul acestor frame buffere trebuie să aibă transparență și să permită lucrul cu valori de tip float în cadrul acestora. Așadar, formatul intern recomandat pentru aceste texturi este GL_RGBA32F, iar formatul lor GL_RGBA.
  3. Pentru fiecare shader care randează obiectele în scenă normal, trebuie să avem și un shader corespunzător care randeaza obiectele în textura de tip cubemap (procesul poate fi automatizat, dar depășește scopul acestei teme).
  4. La pasul de light accumulation pentru a face sampling al texturilor nu mai putem folosi coordonate de textură normale, ci trebuie să specificăm vectori de direcție. Puteți folosi această funcție care calculează vectorii de direcție aferenți coordonatelor de textură ale unei fețe: faceIndex poate avea valoarea gl_Layer, iar uv poate avea valoarea coordonatelor de textură folosite în laboratorul despre maparea mediului.
  5. Dacă apar probleme la pasul de light accumulation, puteți dezactiva complet GL_DEPTH_TEST

Rezultatul ar trebui să arate în felul următor:

După cum se observă, reflexia nu este una perfectă, ci doar o aproximare. Această variantă de implementare este cea propusă pentru că se leagă de laboratoarele anterioare. Totuși puteți folosi și o metodă alternativă pentru redarea reflexiilor, metodă care oferă rezultate realiste.

Metoda realistă este următoarea: Se folosește un frame buffer pentru a randa scena folosind o cameră care este dedesubtul apei, simetrică față de camera jucătorului. De asemenea, pentru a nu apărea artefacte vizuale, trebuie sa nu se mai randeze fragmentele obiectelor de sub suprafața apei (folosind gl_CullDistance). Imaginea rezultată de această cameră este flipped pe verticală, iar apoi mapata pe suprafața apei folosind coordonatele NDC ale pixelilor de pe ecran.

Cascada

În cadrul acestei cerințe se va implementa un sistem de particule pentru simularea unei cascade. Particulele vor urma o traiectorie definită de curba Bezier descrisă anterior, iar pentru a genera un efect natural, fiecare particulă va avea un offset aleatoriu față de această curbă. Particulele se vor deplasa pe curba Bezier cu un increment al parametrului t. Valorile pentru acest increment, precum și pentru valoarea de noise sunt la latitudinea voastră (alegeți valori astfel încât să obțineți un efect realist).

Comparativ cu implementarea din cadrul laboratorului de particule, particulele cascadei nu vor avea transparență aplicată prin blending; în schimb, pentru a evita incompatibilități cu tipul de randare deferred, se vor elimina (discard) pixelii transparenți din texturile folosite.

De asemenea, sistemul de particule pentru cascadă trebuie să aibă activat testul de adâncime.

Pentru a nu complica aplicația, particulele NU trebuie să se reflecte pe suprafața apei (decât dacă doriți să implementați această funcționalitate).

Notare (250)

  • Generarea terenului (75)
    • Generarea formei de munti & lac (25)
    • Noise (25)
    • Curbura pentru cascada (25)
  • Cerul (50)
    • Skybox (20)
    • Puncte de lumină mișcătoare (30)
  • Petic de apa (75)
    • Reflexie (25)
    • Pastarea iluminarii in reflexie (50)
  • Cascada folosind sistem de particule (50)

Bonusuri posibile

  • Refractie
  • Stele
  • Licurici in loc de lumini simple
  • Particule folosind blending in deferred rendering (care sa tina cont de depth-ul scenei)
  • Reflexie a particulelor

Indicații suplimentare

Tema va fi implementată în OpenGL și C++. Este indicat să folosiți framework-ul și Visual Studio.

Pentru implementarea temei, în folderul src/lab_m2 puteți crea un nou folder, de exemplu Tema1, cu fișierele Tema1.cpp și Tema1.h (pentru implementare POO, este indicat să aveți și alte fișiere). Pentru a vedea fișierele nou create în Visual Studio în Solution Explorer, apăsați click dreapta pe filtrul lab_m2 și selectați Add→New Filter. După ce creați un nou filtru, de exemplu Tema1, dați click dreapta și selectați Add→Existing Item. Astfel adăugați toate fișierele din folderul nou creat. În fișierul lab_list.h trebuie adăugată și calea către header-ul temei. De exemplu: #include “lab_m2/Tema1/Tema1.h”.

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 curățat proiectul Visual Studio:
    • click dreapta pe proiect în Solution ExplorerClean Solution
    • și ștergeți folderul /build/.vs (dacă nu il vedeți, este posibil să fie ascuns)
  • SAU ștergeți complet folderul /build
  • În cazul în care arhiva tot depășește limita de 50MB (nu ar trebui), puteți să ștergeți și folderul /deps sau /assets î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.

pgapi/teme/2024/01.txt · Last modified: 2024/12/08 16:55 by silviu.stancioiu00
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