Differences

This shows you the differences between two versions of the page.

Link to this comparison view

egc:teme:2024:03 [2024/12/14 18:59]
andrei.lapusteanu Added GIF and more text
egc:teme:2024:03 [2024/12/15 21:43] (current)
andrei.lapusteanu Corrected normal recomputation text (changed vertex height to texel height)
Line 1: Line 1:
-<​hidden>​ 
- 
 ======= Tema 3 - Cappadocian Balloons ======= ======= Tema 3 - Cappadocian Balloons =======
  
Line 10: Line 8:
   * **Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!**   * **Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!**
  
-În cadrul acestei teme veți implementa o scenă virtuală ce face referire la faimoasele baloane cu aer cald Cappadociene ​- se vor studia astfel conceptele de iluminare și texturare. Elementele vizuale principale ce compun scena vor fi un teren texturat și modificat în înălțime printr-un shader, baloanele cu aer cald, precum și un soare la asfințit.+În cadrul acestei teme veți implementa o scenă virtuală ce face referire la faimoasele baloane cu aer cald cappadociene (puteți vizualiza [[https://​sofiaadventures.com/​wp-content/​uploads/​2019/​10/​shutterstock_531058951.jpg|aici]] o imagine de referință) ​- se vor studia astfel conceptele de iluminare și texturare. Elementele vizuale principale ce compun scena vor fi un teren texturat și modificat în înălțime printr-un shader, baloanele cu aer cald, precum și un soare la asfințit.
  
 Puteți studia în următorul videoclip o posibilă implementare a cerințelor. Puteți studia în următorul videoclip o posibilă implementare a cerințelor.
Line 16: Line 14:
 <​html>​ <​html>​
 <p style="​text-align:​center;​margin:​auto;">​ <p style="​text-align:​center;​margin:​auto;">​
-<iframe width="​560"​ height="​315"​ src="​https://​www.youtube.com/​embed/​jq4mYlVD5KI" title="​YouTube video player"​ frameborder="​0"​ allow="​accelerometer;​ autoplay; clipboard-write;​ encrypted-media;​ gyroscope; picture-in-picture"​ allowfullscreen></​iframe>​+<iframe width="​560"​ height="​315"​ src="​https://​www.youtube.com/​embed/​eo0g7awNbsE" title="​YouTube video player"​ frameborder="​0"​ allow="​accelerometer;​ autoplay; clipboard-write;​ encrypted-media;​ gyroscope; picture-in-picture"​ allowfullscreen></​iframe>​
 </p> </p>
 </​html>​ </​html>​
Line 23: Line 21:
  
 Scena va fi compusă dintr-o serie de modele 3D, anume: Scena va fi compusă dintr-o serie de modele 3D, anume:
- +  * **Terenul**:​ Format dintr-un plan (construcția acestuia este specificată în capitolele următoare) 
-// [ TODO, listarea elementelor de interes ]//. Sugerez un capitol separat pentru teren si baloane, intrucat mi-e greu sa le includ doar la un capitol mare de "​texturare",​ intrucat amandoua implica modificari si in VS. +  * **Baloane**:​ Formate din mai multe primitive (construcția ​acestora este specificată în capitolele următoare) 
- +  * **Soarele**:​ Format dintr-sferă
-<​note> ​  +
-Este permisă importarea de mesh-uri create ​în aplicații de modelare 3D +
-</​note>​ +
- +
-Următoarea imagine prezintă un exemplu de construcție al acestor modele. +
- +
-// [TODO IMG ] // +
- +
-==== Construcția scenei ==== +
- +
-// [ TODO daca e de schimbat / adaugat ] // +
- +
-Scena virtuală trebuie configurată astfel încât să se poată vizualiza ​în mod ușor toate elementele de interes. Vă recomandăm ​configurație similară cu cea prezentată în demo.+
  
 ==== Poziționarea camerei ==== ==== Poziționarea camerei ====
Line 48: Line 33:
 Baloanele din scenă sunt construite folosind o serie de primitive. Varianta recomandată,​ care este utilizată și în demo, are următoarele componente: Baloanele din scenă sunt construite folosind o serie de primitive. Varianta recomandată,​ care este utilizată și în demo, are următoarele componente:
  
-1. Nacela – paralelipiped +  - Nacela – paralelipiped 
- +  ​- ​Corp balon – sferă (cu deformarea propusă mai jos) 
-2. Corp balon – sferă (cu deformarea propusă mai jos) +  ​- ​Conectoare – 4 paralelipipede 
- +{{ :​egc:​teme:​2024:​ballonconstructionref1.png?400 |}}
-3. Conectoare – 4 paralelipipede +
- +
-{{ :​egc:​teme:​2024:​ballonconstructionref.png?400 |}}+
  
  
Line 63: Line 45:
  
 {{ :​egc:​teme:​2024:​ballondisp.gif?​400 |}} {{ :​egc:​teme:​2024:​ballondisp.gif?​400 |}}
- 
  
 Veți face această deformare raportându-vă la coordonatele obiect ale sferei. O simplă verificare a modelului disponibil în framework (sphere.obj) vă va arăta că acesta este definit în origine și are rază 1. Vârfurile care sunt mutate ​ au coordonata y intre [0, -0.5] în coordonate obiect. Observați că referința realizează un deplasament diferit în funcție de această valoare 😊. Veți face această deformare raportându-vă la coordonatele obiect ale sferei. O simplă verificare a modelului disponibil în framework (sphere.obj) vă va arăta că acesta este definit în origine și are rază 1. Vârfurile care sunt mutate ​ au coordonata y intre [0, -0.5] în coordonate obiect. Observați că referința realizează un deplasament diferit în funcție de această valoare 😊.
- 
- 
  
 ==== Texturare ==== ==== Texturare ====
Line 75: Line 54:
 {{ :​egc:​teme:​2024:​ballontexturingref.png?​400 |}} {{ :​egc:​teme:​2024:​ballontexturingref.png?​400 |}}
  
 +==== Comportamentul baloanelor ====
  
 +Baloanele din scenă trebuie să se rotească pe traiectorii concentrice. Traiectoriile sunt sub formă de cercuri paralele cu planul \(XOZ\) și cu centrul comun. Pentru acest lucru trebuie să alegeți un punct din planul \(XOZ\), \(\mathbf{C}\) (de exemplu \((0, 0)\)), pentru a desemna centrul cercurilor. ​
  
-==== Comportamentul baloanelor ====+Pentru fiecare balon trebuie să se aleagă (de preferat aleator) o înălțime \(\mathbf{H}\) la care să se rotească (astfel centrul traiectoriei va fi \((C.x, H, C.y)\)), o rază \(\mathbf{R}\) a cercului care descrie traiectoria și o viteză de rotație \(\omega\). Rezultatul va fi o serie de traiectorii concentrice paralele cu \(XOZ\) și paralele între ele, la înălțimi diferite față de pământ. ​
  
-Baloanele din scenă trebuie să se rotească pe traiectorii concentrice. Traiectoriile sunt sub formă de cercuri paralele cu planul XOZ și cu centrul comun. Pentru acest lucru trebuie să alegeți un punct din planul XOZ **C** (ex: (0, 0)) pentru a desemna centrul cercurilor. Pentru fiecare balon trebuie să se aleagă (de preferat random) o înălțime **H** la care să se rotească (astfel centrul traiectoriei o sa fie **(C.x, H, C.y)**, o rază **R** a cercului care descrie traiectoria și o viteză de rotație **W**. Rezultatul va fi o serie de traiectorii concentrice paralele cu XOZ și parelele între ele la înalțimi diferite față de pamânt. ​În plus, pentru un efect mai realist ​fiecare balon va avea o oscilație pe axa OY de forma **Δy = A sin(ω * Δt)** (unde A și ω se vor alege astfel încât efectul vizual să pară realist).+În plus, pentru un efect mai realistic, ​fiecare balon va avea o oscilație pe axa \(OY\) de forma \(\Delta ​y = A \cdot \sin(\omega \cdot \Delta ​t)\) (unde \(A\) și \(\omega\) ​se vor alege astfel încât efectul vizual să pară realistic).
  
 ===== Construcția terenului ===== ===== Construcția terenului =====
Line 87: Line 68:
 {{ :​egc:​teme:​2024:​terraingeometry.png?​400 |}} {{ :​egc:​teme:​2024:​terraingeometry.png?​400 |}}
  
-Un astfel de model se găsește aici: [TODO] (arhiva cu .obj)+<​note>​Un astfel de model, ce are 256x256 de quad-uri, ​se găsește aici: {{:​egc:​teme:​2024:​plane256.zip|}}</​note>​
  
-==== Deformare în Vertex Shader folosind ​un height map ====+==== Deformare în Vertex Shader folosind ​o hartă de înălțime ​====
  
 Veți realiza deformarea în Vertex Shader luând informația de înălțime din textură, la care veți aplica un factor de intensificare constant în funcție de rezultatul dorit. Veți realiza deformarea în Vertex Shader luând informația de înălțime din textură, la care veți aplica un factor de intensificare constant în funcție de rezultatul dorit.
Line 95: Line 76:
 <code cpp> <code cpp>
 // GLSL code // GLSL code
-const float HEIGHT_OFFSET ​15.;+const float Y_OFFSET ​0.5;
 // Get vertex height from the height map // Get vertex height from the height map
-new_position.y = HEIGHT_OFFSET ​* texture(texture_1,​ v_texture_coord).r;​+new_position.y = Y_OFFSET ​* texture(texture_1,​ v_texture_coord).r;​
 </​code>​ </​code>​
  
Line 104: Line 85:
 {{ :​egc:​teme:​2024:​heightmap.png?​400 |}} {{ :​egc:​teme:​2024:​heightmap.png?​400 |}}
  
-Puteți prelua harta de înălțimi folosită în referință de aici: [TODO] arhiva heighmap  +<​note>​Puteți prelua harta de înălțimi folosită în referință, de rezoluție 256x256, ​de aici: {{:​egc:​teme:​2024:​heightmap256.zip|}}</​note>​
  
 ==== Texturare ==== ==== Texturare ====
  
 Terenul, reprezentat de planul subdivizat, se va textura folosind coordonatele sale de textură. Pentru a obține un efect interesant vă veți folosi de două texturi de culoare, împreună cu textura de adâncime. Fiecare fragment se colorează în funcție de înălțime. ​ Pentru o trecere uniformă este necesară interpolarea liniară în zonele de înălțime medie. Ideea este evidențiată de diagrama de mai jos: Terenul, reprezentat de planul subdivizat, se va textura folosind coordonatele sale de textură. Pentru a obține un efect interesant vă veți folosi de două texturi de culoare, împreună cu textura de adâncime. Fiecare fragment se colorează în funcție de înălțime. ​ Pentru o trecere uniformă este necesară interpolarea liniară în zonele de înălțime medie. Ideea este evidențiată de diagrama de mai jos:
 +{{ :​egc:​teme:​2024:​groundlerpdiag2.png?​400 |}}
  
-{{ :​egc:​teme:​2024:​groundlerpdiag1.png?​400 |}} 
  
-Funcția care indică gradul de interpolare trebuie să normalizeze intervalul de mijloc [LOW_LIMIT, HIGH_LIMIT] în [0, 1]. Aceasta poate să arate așa: f(height) = (height ​– LOW_LIMIT) * 1 / ( HIGH_LIMIT ​– LOW_LIMIT)+Funcția care indică gradul de interpolare trebuie să normalizeze intervalul de mijloc ​\(\text{LOW_LIMIT}\text{HIGH_LIMIT]\) în \([0, 1]\). Aceasta poate să arate așa: 
 + 
 +\[ 
 +f(\text{height}) = \frac{\text{height} - \text{LOW_LIMIT}}{\text{HIGH_LIMIT} - \text{LOW_LIMIT}} 
 +\]
  
 Rezultatul pe care trebuie să îl obțineți este următorul: Rezultatul pe care trebuie să îl obțineți este următorul:
Line 121: Line 105:
 ==== Recalculare normale ==== ==== Recalculare normale ====
  
-// [ TODO ce e in VSexplicatiiimaginicodetc.] //+Deformarea aplicată în vertex shader se aplică asupra poziției fiecărui vertexurmărind metodolgia prezentată mai sus. Totușiamintiți-vă de formulele de la calculele de iluminare - acestea se bazează pe vectorul normală la suprafață (\(\vec{N}\))care a rămas neschimbat în urma deplasării vertecșilorceea ce conduce la un rezultat eronat al iluminării.
  
-Deformarea aplicată în vertex shader se aplică asupra poziției fiecări vertex, urmărind metodolgia prezentată mai sus. Totuși, amintiți-vă de formulele de la calculele de iluminare - acestea se bazează pe vectorul normală la suprafață (\(\vec{N}\)),​ care a rămas neschimbat în urma deplasării vertecșilor,​ ceea ce conduce la un rezultat eronat al iluminării. ​În imaginea următoare este desenat terenul deformat și o lumină punctiformă - observați diferențele între imagini, in partea stângă normalele planului sunt toate orientate către \(\text{(0,​1,​0)}\),​ iar imaginea ​dreptă ​ilustrează rezultatul după recalcularea normalelor.+În imaginea următoare este desenat terenul deformat și o lumină punctiformă - observați diferențele între imagini, in partea stângă normalele planului sunt toate orientate către \(\text{(0,​1,​0)}\),​ iar imaginea ​din dreapta ​ilustrează rezultatul după recalcularea normalelor.
  
 {{ :​egc:​teme:​2024:​egc_2024_t3_recompute_normals_2.png?​750 |}} {{ :​egc:​teme:​2024:​egc_2024_t3_recompute_normals_2.png?​750 |}}
  
-La nivel conceptual, ne vom folosi de metoda diferențelor finite pentru a aproxima aceste normale. Pentru coordonatele de texturare ale fiecărui vertex vom eșantiona ​height map-ul, unde ne vom folosi de texelii vecini pentru a determina aceste normale.+La nivel conceptual, ne vom folosi de metoda diferențelor finite pentru a aproxima aceste normale. Pentru coordonatele de texturare ale fiecărui vertex vom eșantiona ​harta de înălțimi, unde ne vom folosi de texelii vecini pentru a determina aceste normale.
  
-Pentru a calcula \(\text{texelSize}\),​ presupunem că height map-ul ​este o imagine pătratică,​ iar dimensiunea sa (rezoluția) este \(\text{dim}\). Texelul reprezintă o unitate discretă a texturii, iar dimensiunea sa relativă în coordonate UV se poate calcula astfel:+Pentru a calcula \(\text{texelSize}\),​ presupunem că harta de înălțimi ​este o imagine pătratică,​ iar dimensiunea sa (rezoluția) este \(\text{dim}\). Texelul reprezintă o unitate discretă a texturii, iar dimensiunea sa relativă în coordonate UV se poate calcula astfel:
  
  
Line 136: Line 120:
 \] \]
  
-Se eșantionează textura suport (heightmap-ul) pentru a determina înălțimea ​fiecărui vertex. Se folosesc coordonatele de textură (\(v_{\text{texCoord}}\)) pentru a extrage valoarea înălțimii corespunzătoare (\(h\)), dar și valorile de înălțime ale vecinilor acestuia, de-a lungul axelor X și Z.+Se eșantionează textura suport (harta de înălțimi) pentru a determina ​"înălțimea" texelilor (în esență, se identifică valoarea de luminozitate a texelului, pe care o notăm cu (\(h\))). Se folosesc coordonatele de textură (\(v_{\text{texCoord}}\)) pentru a extrage valoarea înălțimii corespunzătoare (\(h\)), dar și valorile de înălțime ale vecinilor acestuia, de-a lungul axelor X și Z.
  
 \[ \[
Line 144: Line 128:
 \] \]
  
-Următorul pas este calcularea gradientelor pe direcțiile X și Z. Factorul de scalare pe verticală \((y_{\text{offset}})\) reprezintă valoarea utilizată anterior pentru ajustarea înălțimii terenului pe baza height map-ului:+Următorul pas este calcularea gradientelor pe direcțiile X și Z. Factorul de scalare pe verticală \((y_{\text{offset}})\) reprezintă valoarea utilizată anterior pentru ajustarea înălțimii terenului pe baza hărții de înălțimi:
  
 \[ \[
Line 177: Line 161:
 {{ :​egc:​teme:​2024:​egc_2024_t3_recompute_normals_3.png?​300 |}} {{ :​egc:​teme:​2024:​egc_2024_t3_recompute_normals_3.png?​300 |}}
  
-În final, animația de mai jos ilustrează cum sunt normalele recalculate în funcție de înălțimea terenului, precum și rezultatul în cazul unei lumini direcționale.+În final, animația de mai jos ilustrează cum sunt normalele recalculate în funcție de înălțimea terenului, precum și rezultatul ​obținut ​în urma adăugării ​unei lumini direcționale.
  
 {{ :​egc:​teme:​2024:​egc_2024_t3_recompute_normals_4.gif?​400 |}} {{ :​egc:​teme:​2024:​egc_2024_t3_recompute_normals_4.gif?​400 |}}
Line 187: Line 171:
 Iluminarea scenei se va realiza folosind cel puțin 2 tipuri de surse de lumină: **punctiformă** și **direcțională**. Fiecare sursă de lumină (indiferent de tipul acesteia) o să aibă o culoare specifică și trebuie să se țină cont de această culoare în calculele de iluminare. Iluminarea scenei se va realiza folosind cel puțin 2 tipuri de surse de lumină: **punctiformă** și **direcțională**. Fiecare sursă de lumină (indiferent de tipul acesteia) o să aibă o culoare specifică și trebuie să se țină cont de această culoare în calculele de iluminare.
  
-<​note>​Iluminarea trebuie să fie implementată folosind **modelul de reflexie ​Phong**, precum și **modelul de calcul al reflexiei luminii Phong**.</​note>​+<​note>​Iluminarea trebuie să fie implementată folosind **modelul de shading ​Phong**, precum și **modelul de calcul al reflexiei luminii Phong**.</​note>​
  
-**Lumina punctiformă:​** Aceasta este reprezentată de sursele care emit lumina cu aceeași intensitate ​indiferent de direcție. Acest tip de lumină trebuie implementat pentru +**Lumina punctiformă:​** Aceasta este reprezentată de sursele care emit lumina cu aceeași intensitate ​in toate direcțiile. Acest tip de lumină trebuie implementat pentru **fiecare ​balon cu aer cald**: Lumina trebuiă să ramână la o poziție fixă relativ la balon și să aibă o culoare și intensitate luminoasă aleatorie.
-    ​Fiecare ​balon cu aer cald: Lumina trebuiă să ramână la o poziție fixă relativ la balon și să aibă o culoare și intensitate luminoasă aleatorie+
  
 În următoarea imagine au fost activate numai luminile punctiforme:​ În următoarea imagine au fost activate numai luminile punctiforme:​
  
-// [ TODO IMG ] //+{{ :​egc:​teme:​2024:​egc_2024_t3_lights_1.2.png?​500 |}}
  
-**Lumina direcțională:​** aceasta va ilumina toate obiectele din scenă cu aceeași intensitate. Specific luminii de tip direcțional este faptul că vectorul luminii incidente $L$ nu depinde de poziția luminii sau a fragmentului care trebuie iluminat (precum în cazul luminilor de tip point și spot). Așadar, pentru fiecare fragment, iluminarea va fi calculată folosind același vector $L$ (corespunzător direcției luminii). Astfel, pentru o sursă de lumină de tip direcțional este nevoie să se definească direcția acesteia și culoarea luminii emise. În cadrul acestei teme vom considera ​luna ca `sursa` acestei lumini direcționale,​ așadar, va trebui să setați direcția acestei lumini în mod corespunzător.+<note important>​ 
 +Implementarea voastră trebuie să suporte **randarea mai multor surse de lumină în același frame!** 
 +</​note>​ 
 + 
 +**Lumina direcțională:​** aceasta va ilumina toate obiectele din scenă cu aceeași intensitate. Specific luminii de tip direcțional este faptul că vectorul luminii incidente $L$ nu depinde de poziția luminii sau a fragmentului care trebuie iluminat (precum în cazul luminilor de tip point și spot). Așadar, pentru fiecare fragment, iluminarea va fi calculată folosind același vector $L$ (corespunzător direcției luminii). Astfel, pentru o sursă de lumină de tip direcțional este nevoie să se definească direcția acesteia și culoarea luminii emise. În cadrul acestei teme vom considera ​soarele ​ca `sursa` acestei lumini direcționale,​ așadar, va trebui să setați direcția acestei lumini în mod corespunzător.
  
 În următoarea imagine a fost activată numai lumina direcțională:​ În următoarea imagine a fost activată numai lumina direcțională:​
  
-// [ TODO IMG ] // +{{ :​egc:​teme:​2024:​egc_2024_t3_lights_2.png?​500 |}}
- +
-<note important>​Implementarea voastră trebuie să suporte **randarea mai multor surse de lumină în același frame!** +
-</​note>​ +
- +
-===== Barem =====+
  
-**TODO**+===== Barem [150p] =====
  
-===== Exemple ​de Funcționalități Bonus=====+  * **Construcția baloanelor [30p]** 
 +    * Asamblarea componentelor [7.5p] 
 +    * Deformarea balonului in Vertex Shader [15p] 
 +    * Texturarea [7.5p] 
 +  * **Dinamica baloanelor [20p]** 
 +    * Randarea a minim 5 baloane [5p] 
 +    * Deplasarea baloanelor (fiecare cu rază diferită) în jurul unui punct [15p] 
 +  * **Construcția terenului [60p]** 
 +    * Desenarea terenului (plan) [5p] 
 +    * Deformarea în Vertex Shader folosind o hartă ​de înălțime [10p] 
 +    * Texturarea [15p] 
 +      * Folosirea a minim 2 texturi [10p] 
 +      * Interpolarea între texturi pe baza înălțimii [5p] 
 +    * Recalcularea normalelor [30p] 
 +  * **Iluminarea [40p]** 
 +      * Lumină direcțională [15p] 
 +        * Desenarea modelului de soare (cu o culoare uniformă) [5p] 
 +        * Calcule pentru iluminarea direcțională [10p] 
 +      * Lumini punctiforme [25p] 
 +        * Câte o lumină de culoare șintensitate aleatorie pentru fiecare balon [25p]
  
-  * Unele baloane să aibă o traiectorie definită ​de un set de puncte generate random și să interpozele printre ele. +===== Exemple ​de Funcționalități Bonus =====
-  * Pe un balon să se simuleze efectul gravitației șefectul unui vânt cu o forță random care se schimbă în timp. În plus, la apăsarea unei taste balonul să primească o accelerație pe axa OY (se intensifică focul din balon). +
-  * Să se genereze la fiecare rulare un height map diferit care să se adune la cel de bază pentru a avea variații ale terenului la fiecare run.+
  
 +  * Unele baloane să aibă o traiectorie definită de un set de puncte generate aleatoriu și să se interpoleze poziția acestora între ele.
 +  * Pe un balon să se simuleze efectul gravitației și efectul unui vânt cu o forță aleatorie care se schimbă în timp. În plus, la apăsarea unei taste balonul să primească o accelerație pe axa OY (se intensifică focul din balon).
 +  * Să se genereze la fiecare rulare o hartă de înălțime diferită care să se adune la cea de bază pentru a avea variații ale terenului la fiecare rulare.
  
 ===== Întrebări și răspunsuri ===== ===== Întrebări și răspunsuri =====
Line 242: Line 244:
   * Î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.   * Î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.
 </​note>​ </​note>​
- 
-</​hidden>​ 
egc/teme/2024/03.1734195577.txt.gz · Last modified: 2024/12/14 18:59 by andrei.lapusteanu
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