This shows you the differences between two versions of the page.
|
egc:teme:2024:03 [2024/12/14 19:43] 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> | ||
| 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-o 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 o 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) | ||
| + | - 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 77: | 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 85: | Line 68: | ||
| {{ :egc:teme:2024:terraingeometry.png?400 |}} | {{ :egc:teme:2024:terraingeometry.png?400 |}} | ||
| - | <note>Un astfel de model, ce are 256x256 de quad-uri, se găsește aici: {{:egc:teme:2024:heightmap256.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 113: | 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 128: | Line 105: | ||
| ==== 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ă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 din dreapta 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 dreptă 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 145: | 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 153: | 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 186: | 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 196: | 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 **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 208: | 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 214: | 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 251: | 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> | ||