Differences

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

Link to this comparison view

egc:teme:2024:03 [2024/12/14 20:32]
andrei.lapusteanu
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>​
  
 ===== Scena virtuală ===== ===== Scena virtuală =====
 +
 +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)
 +  * **Baloane**:​ Formate din mai multe primitive (construcția acestora este specificată în capitolele următoare)
 +  * **Soarele**:​ Format dintr-o sferă
  
 ==== Poziționarea camerei ==== ==== Poziționarea camerei ====
Line 30: 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) 
 +  - Conectoare – 4 paralelipipede 
 +{{ :​egc:​teme:​2024:​ballonconstructionref1.png?​400 |}}
  
-2. Corp balon – sferă (cu deformarea propusă mai jos) 
- 
-3. Conectoare – 4 paralelipipede 
- 
-{{ :​egc:​teme:​2024:​ballonconstructionref.png?​400 |}} 
  
 ==== Deformare în Vertex Shader ==== ==== Deformare în Vertex Shader ====
Line 59: Line 60:
 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. ​ 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. ​
  
-În plus, pentru un efect mai realist, 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ă 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 69: Line 70:
 <​note>​Un astfel de model, ce are 256x256 de quad-uri, se găsește aici: {{:​egc:​teme:​2024:​plane256.zip|}}</​note>​ <​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 ​\((y_{\text{offset}})\) ​î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.
  
 <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>​
- 
-**V2** 
- 
-\[ 
-v\_pos.y = y_{\text{offset}} \cdot texture(\text{heightMap},​ v_{\text{texCoord}}).r 
-\] 
  
 Rezultatul pe care îl veți obține este următorul: Rezultatul pe care îl veți obține este următorul:
Line 95: Line 90:
  
 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 \([ \text{LOW_LIMIT},​ \text{HIGH_LIMIT} ]\) în \([0, 1]\). Aceasta poate să arate așa: 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:
Line 109: Line 104:
  
 ==== Recalculare normale ==== ==== Recalculare normale ====
- 
-// [ TODO ce e in VS, explicatii, imagini, cod, etc.] // 
  
 Deformarea aplicată în vertex shader se aplică asupra poziției fiecărui 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. Deformarea aplicată în vertex shader se aplică asupra poziției fiecărui 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.
Line 118: Line 111:
 {{ :​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 127: Line 120:
 \] \]
  
-Se eșantionează textura suport (harta de înălțimi) 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 135: 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 168: 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 180: Line 173:
 <​note>​Iluminarea trebuie să fie implementată folosind **modelul de shading 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 **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.+**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.
  
 În următoarea imagine au fost activate numai luminile punctiforme:​ În următoarea imagine au fost activate numai luminile punctiforme:​
Line 190: Line 183:
 </​note>​ </​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 ​luna ca `sursa` acestei lumini direcționale,​ așadar, va trebui să setați direcția acestei lumini în mod corespunzător.+**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ă:​
Line 196: Line 189:
 {{ :​egc:​teme:​2024:​egc_2024_t3_lights_2.png?​500 |}} {{ :​egc:​teme:​2024:​egc_2024_t3_lights_2.png?​500 |}}
  
-===== Barem =====+===== Barem [150p] ​=====
  
-**TODO**+  ​* **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 și intensitate aleatorie pentru fiecare balon [25p]
  
-===== Exemple de Funcționalități Bonus===== +===== Exemple de Funcționalități Bonus =====
- +
-  * Unele baloane să aibă o traiectorie definită de un set de puncte generate random și să interpozele printre ele. +
-  * Pe un balon să se simuleze efectul gravitației și 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 233: 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.1734201160.txt.gz · Last modified: 2024/12/14 20:32 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