Tema 1 - AR Mirror

  • Responsabili: Anca Morar, Anca Băluțoiu, Robert Caragicu
  • Lansare: 15 noiembrie 2023
  • Termen de predare: 15 decembrie 2023, 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ă implementați un demo tehnic ce utilizează și prezintă cunoștințele acumulate. Un video demonstrativ ce înfățișează o posibilă implementare îl puteți viziona în continuare:

Ideea temei este utilizarea unei oglinzi de realitate augmentată (AR) care reflectă mediul înconjurător, dar augmentat. Astfel:

  • în mod uzual, oglinda va reflecta mediul înconjurător nemodificat
  • la apăsarea unei taste, oglinda va reflecta numai contururile obiectelor din mediul înconjurător
  • la apăsarea unei taste, oglinda va reflecta mediul înconjurător, în care va apărea un sistem de particule sub forma unor licurici care urmăresc traiectoriile unor curbe Bezier.

Afișarea conturului unui obiect 3D

Considerăm un triunghi care aparține unui obiect 3D, cu normala $N$ a feței, în spațiul lume. De asemenea, considerăm vectorul de vizualizare (direcția forward a camerei), $V$, în spațiul lume. Dacă unghiul dintre vectorul de vizualizare și normala $N$:

  • este mai mic de 90 de grade, atunci fața respectivă este orientată spre observator (FRONT_FACE)
  • e mai mare de 90 de grade, fața este auto-obturată (BACK_FACE)

Conturul obiectului este format din muchiile care conectează fețe FRONT_FACE cu fețe BACK_FACE. Totuși, acest contur este destul de zimțat.

Există mai multe metode de afișarea conturului unui obiect 3D. În cadrul acestei teme va trebui să utilizați tehnica prezentată mai jos.

În cadrul temei, vom extinde algoritmul prezentat mai sus, la nivel de vârf. Considerăm că fiecare vârf al triunghiului are o normală diferită: $N_1$, $N_2$, $N_3$. Dacă unghiul dintre vectorul de vizualizare și normala unui vârf:

  • este mai mic de 90 de grade ($dot>0$), atunci considerăm că acel vârf este “orientat” spre observator
  • e mai mare de 90 de grade ($dot<0$), vârful este “orientat” în sens invers
  • este egal cu 90 grade ($dot=0$), atunci vârful respectiv face parte din contur.

Dacă un triunghi are și vârfuri orientate spre observator, și vârfuri care sunt orientate în sens invers, atunci considerăm că acel triunghi conține un segment de contur. Vârfurile segmentului de contur se vor determina prin interpolare între vârfurile triunghiului.

În figura de mai sus, $P_2$ este “orientat” către observator (produsul scalar dintre $N_2$ și $V$, $dot_2> 0$), iar $P_1$ și $P_3$ sunt “orientate” în sens invers. Astfel, pe muchiile $P_1P_2$ și $P_2P_3$ se află câte un vârf de pe contur, $P_{12}$, respectiv $P_{23}$. $P_{12}$ și $P_{23}$ se calculează prin interpolare între vârfurile $P_1$ și $P_2$, respectiv $P_2$ și $P_3$, ținând cont că normalele lui $P_{12}$ și $P_{23}$ sunt perfect perpendiculare pe vectorul de vizualizare ($dot_{12}=0$, $dot_{23}=0$).

Vectorul de vizualizare (al camerei care este utilizată pentru redarea scenei în buffer-ul de culoare default) se poate obține cu următoarea funcție:

 GetSceneCamera()->m_transform->GetLocalOZVector(); 

Sistemul de particule

Sistemul de particule emite “licurici” care urmează traiectoriile unor curbe Bezier. În cele ce urmează vor fi descrise proprietățile sistemului de particule. În cadrul temei puteți varia aceste proprietăți, atât timp cât rezultatul este unul asemănător cu cel din video. Sistemul de particule conține 100 de elemente. O particulă conține următoarele proprietăți:

struct Particle
{
    glm::vec4 position;
    glm::vec4 speed;
    glm::vec4 initialPos;
    glm::vec4 initialSpeed;
    float delay;
    float initialDelay;
    float lifetime;
    float initialLifetime;
}

Proprietățile sistemului de particule sunt următoarele:

  • Poziția inițială a fiecărei particule este $(0,0,0)$
  • Fiecare particulă are o viteză aleatoare
  • Fiecare particulă are o întârziere (delay) și o durată de viață (lifetime) alese aleator (se pot utiliza formule similare cu cele din laboratorul de particule).
  • Traiectoria (variabila position) fiecărei particule urmărește una din cele 5 curbe Bezier (în funcție de ID-ul particulei curente, se alege un set de puncte de control $C_0$, $C_1$, $C_2$, $C_3$ care determină expresia curbei). Parametrul $t$ care modelează curba Bezier se calculează în funcție de durata de viață a particulei curente :t = 0 atunci când lifetime = initialLifetime și t = 1 atunci când lifetime = 0)
  • Atunci când durata de viață a particulei s-a scurs (lifetime < 0), poziția și durata de viață se resetează la valorile inițiale.

Reflexia dinamică a mediului înconjurător

Mediul înconjurător va conține un skybox static (puteți folosi texturile din laboratorul 6) și o serie de obiecte dinamice (puteți folosi arcașii din laboratorul 6 și/sau alte obiecte pe care se aplică animații de translație/rotație/scalare).

Se va desena în scenă o oglindă (un quad) care poate fi deplasată (translație pe axele $Ox$, $Oy$, $Oz$) și rotită (față de axele $Ox$, $Oy$, $Oz$) din taste. Din poziția oglinzii se va desena un cubemap într-un framebuffer. Apoi se va folosi acel cubemap din framebuffer pentru a reda reflexia mediului înconjurător pe oglindă:

  • În mod default, pe oglindă se va reda reflexia mediul înconjurător nemodificat
  • La apăsarea unei taste, pe oglindă se vor reda numai contururile obiectelor din mediul înconjurător. Aceste contururi se vor vedea numai în oglindă, mediul înconjurător rămânând nemodificat la redarea în buffer-ul de culoare default
  • La apăsarea unei taste, pe oglindă se va reda mediul înconjurător, dar și sistemul de particule cu licuricii care urmăresc traiectoriile unor curbe Bezier. Generatoarea sistemului de particule rămâne permanent în poziția $(0,0,0)$. Mediul înconjurător redat în buffer-ul de culoare default rămâne nemodificat (adică nu conține un sistem de particule).

Desenarea cu cele 6 camere se va realiza într-un singur pas de rasterizare. Acest lucru va fi posibil prin utilizarea unui framebuffer ce conține o textură cubemap. Pe fiecare față a texturii cubemap se va desena geometria din punctul de vizualizare a uneia din cele 6 camere (ca în laboratorul 6).

Pentru a obține acest rezultat, în geometry shader se emite de 6 ori geometria, o dată pentru fiecare față. Cele 6 versiuni ale geometriei sunt identice în spatiul obiectului. Se folosesc 6 matrici de transformare în spații de vizualizare diferite, câte una pentru fiecare cameră și se calculează pozițiile vârfurilor emise în spațiul de vizualizare a fiecărei camere. Cele 6 versiuni diferite ale geometriei în spațiul de vizualizare sunt trimise spre rasterizare și sunt desenate într-una din cele 6 texturi de culoare ale framebuffer-ului. Textura în care se va desena se alege pe baza feței corespunzătoare spațiului de vizualizare al camerei în care a fost proiecată geometria.

Cele 6 texturi de culoare ale framebuffer-ului vor fi pătrate pentru a se mapa fără deformare pe fețele interioare ale cubului. Nu este necesară o rezoluție mare a fiecărei texturi. Rezoluția de 512×512 / 1024×1024 este suficientă.

La desenarea conturului în cubemap, de fiecare dată se va lua în considerare vectorul de vizualizare corespunzător feței curente a cubului (de exemplu, pentru fața X pozitivă se va considera vectorul $(1,0,0)$).

Notare (250)

  • Desenarea contururilor (90p in total)
    • Verificarea dacă un vârf este orientat sau nu către observator (20p)
    • Determinarea muchiilor triunghiului care conțin un punct de pe contur (20p)
    • Modificarea vectorului de vizualizare în funcție de fața curentă a cubemap-ului (10)
    • Determinarea poziției punctelor de pe contur prin interpolare și emiterea primitivelor (40p)
  • Sistemul de particule (80p in total)
    • Fiecare particulă are viteză și delay diferite (15p)
    • Fiecare particulă urmărește traiectoria unei curbe Bezier (50p)
    • Curbe Bezier diferite în funcție de ID-ul particulei (15p)
  • Desenarea pe fețele cubemap-ului din framebuffer (80p in total)
    • Generarea matricilor de vizualizare din perspectiva fiecarei fete a cubemap-ului din framebuffer (20p)
    • Desenarea si colorarea geometriei din directia fiecarei fete a cubemap-ului din framebuffer (30p)
    • Desenarea diferită (a mediului înconjurător, a conturului, a mediului + sistemul de particule) la apăsarea unei taste (10p)
    • Salvarea imaginilor rezultate in framebuffer (10p)
    • Aplicarea texturii cubemap-ului din framebuffer pe oglinda (10p)

Bonusuri posibile

  • Alte efecte interesante aplicate scenei

Indicații suplimentare

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

Pentru implementarea temei, in folderul src/lab_m2 puteti crea un nou folder, de exemplu Tema1, cu fisierele Tema1.cpp si Tema1.h (pentru implementare POO, este indicat sa aveti si alte fisiere). Pentru a vedea fisierele nou create in Visual Studio in Solution Explorer, apasati click dreapta pe filtrul lab_m2 si selectati Add→New Filter. Dupa ce creati un nou filtru, de exemplu Tema1, dati click dreapta si selectati Add→Existing Item. Astfel adaugati toate fisierele din folderul nou creat. In fisierul lab_list.h trebuie adaugata si calea catre header-ul temei. De exemplu: #include “lab_m2/Tema1/Tema1.h”

Arhivarea proiectului

  • In mod normal arhiva trebuie sa contina toate resursele necesare compilarii si rularii
  • inainte de a face arhiva asigurati-va ca ati curatat proiectul Visual Studio:
    • click dreapta pe proiect in Solution ExplorerClean Solution
    • si stergeti folderul /build/.vs (daca nu il vedeti, este posibil sa fie ascuns)
  • SAU stergeti complet folderul /build
  • in cazul in care arhiva tot depaseste limita de 50MB (nu ar trebui), puteti sa stergeti si folderul /deps sau /assets intrucat se pot adauga la testare. Nu este recomandat sa faceti acest lucru intrucat ingreuneaza mult testarea in cazul in care versiunea curenta a librariilor/resurselor difera de versiunea utilizata la momentul scrierii temei.

spg/teme/2023/01.txt · Last modified: 2023/12/05 22:07 by anca.morar
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