This shows you the differences between two versions of the page.
egc:teme:2023:03 [2023/12/16 13:22] vlad_matei.draghici |
egc:teme:2023:03 [2023/12/17 20:28] (current) andrei.lapusteanu Fix typo |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | <hidden> | ||
======= Tema 3 - Lighthouse ======= | ======= Tema 3 - Lighthouse ======= | ||
* **Responsabili:** Andrei Lăpușteanu, Vlad-Matei Drăghici, Mihnea-Petruţ-Ilie Mitrache | * **Responsabili:** Andrei Lăpușteanu, Vlad-Matei Drăghici, Mihnea-Petruţ-Ilie Mitrache | ||
* **Lansare:** 18 decembrie 2023 | * **Lansare:** 18 decembrie 2023 | ||
- | * **Termen de predare:** 12 ianuarie 2024, ora 23:59 | + | * **Termen de predare:** 14 ianuarie 2024, ora 23:59 |
* **Regulament:** [[egc:teme:regulament|]] | * **Regulament:** [[egc:teme:regulament|]] | ||
* **Notă:** Această temă este considerată **temă suplimentară** | * **Notă:** Această temă este considerată **temă suplimentară** | ||
Line 12: | Line 11: | ||
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. | ||
+ | |||
+ | <note important>În videoclip interacțiunea cu slider-ele se realizează folosind cursorul - această cerință **nu este impusă**.</note> | ||
<html> | <html> | ||
Line 28: | Line 29: | ||
* **Bărcuțe**: Formate din cel puțin două primitive | * **Bărcuțe**: Formate din cel puțin două primitive | ||
- | <note>Este permisă importarea de mesh-uri create în aplicații de modelare 3D.</note> | + | <note> |
+ | * Este permisă importarea de mesh-uri create în aplicații de modelare 3D | ||
+ | * Primitiva **cilindru** pe care am folosit-o pentru demo o puteți descărca de aici: {{:egc:teme:2023:cylinder.zip|}} | ||
+ | </note> | ||
Următoarea imagine prezintă un exemplu de construcție al acestor modele. | Următoarea imagine prezintă un exemplu de construcție al acestor modele. | ||
Line 38: | Line 42: | ||
==== Construcția scenei ==== | ==== Construcția scenei ==== | ||
- | Scena virtuală trebuie configurată astfel încât să se poate vizualiza în mod ușor toate elementele de interes. Vă recomandăm o configurație similară cu cea prezentată în demo. | + | 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. |
- | ==== [WIP] Comportamentul bărcuțelor ==== | + | ==== Comportamentul bărcuțelor ==== |
- | * Instanțierea a (min) 4 bărcuțe | + | **Instanțiere și construcție**: În scenă vom avem un număr fix de bărcuțe, minim 4. Bărcuțele trebuie să fie modelate a.î. să se poată identifica direcția lor de deplasare. În demo, direcția este indicată de velă. |
- | * Rotația lor în jurul insulei | + | |
- | * Start point și viteză random | + | **Dinamică**: Fiecare bărcuță se va deplasa pe un cerc de rază aleatorie, centrat în poziția farului. Punctul de start pe cerc, definit de unghiul de parcurgere a acestuia, este arbitrar. Viteza unghiulară de deplasare și sensul de rotație se modelează de asemenea aleatoriu. |
- | * Rotirea bărcuței corespunzător traiectoriei | + | <note tip>Valoarea pozitivă sau negativă a vitezei dă sensul deplasării. </note> |
+ | <note important>În timpul deplasării, bărcuțele trebuie să fie orientate conform direcției de deplasare pe cerc. </note> | ||
==== Poziționarea camerei ==== | ==== Poziționarea camerei ==== | ||
Line 57: | Line 62: | ||
==== Texturarea apei ==== | ==== Texturarea apei ==== | ||
- | Pe mesh-ul corespunzător apei va trebui aplicată o textură care se repetă. Pentru a obține o textură care se repetă la ieșirea din spațiului UV (0,0) -> (1,1) este necesar să se seteze wrapping_mode-ul texturii la **GL_REPEAT**. | + | Pe mesh-ul corespunzător apei va trebui aplicată o textură care se repetă. Acest lucru se poate obține prin oricare dintre următoarele 2 moduri: |
- | Acest lucru se poate obține prin oricare dintre următoarele 2 moduri: | + | |
* Folosirea unui mesh (fie importat, fie creat de către voi din cod) ale cărui coordonate de texturare sunt în afara domeniului uzual al spațiului UV (0,0) -> (1,1) | * Folosirea unui mesh (fie importat, fie creat de către voi din cod) ale cărui coordonate de texturare sunt în afara domeniului uzual al spațiului UV (0,0) -> (1,1) | ||
- | * Prin modificarea coordonatelor de texturare în shader. Pentru că apa este formată doar dintr-un singur mesh de plan / quad cu coordonate de texturare în (0,0) -> (1,1) textura apei ar fi întinsă părând zoomed in. Astfel, pentru un efect natural textura apei trebuie să se repete și acest efect se poate obține ușor scalând coordonatele de texturare ale fragmentului. | + | * Prin scalarea coordonatelor de texturare în shader. În cazul în care mesh-ul pentru plan/quad are toate coordonatele de texturare definite în intervalul (0,0) -> (1,1), deoarece acest mesh trebuie scalat în mod semnificativ pentru scena virtuală, simpla aplicare a texturii va conduce la întinderea acesteia pe întreg planul și veți obține un efect 'zoomed-in'. Așadar, va trebui să scalați coordonatele de texturare în shader pentru a repeta textura pe mesh |
- | <note tip>Vă recomandăm utilizarea unei texturi de tip “seamless” pentru acest task.</note> | + | <note tip> |
+ | Nu uitați că este este necesară setarea ''wrapping_mode''-ului texturii cu ''GL_REPEAT''. | ||
+ | De asemenea, vă recomandăm utilizarea unei texturi de tip “seamless” pentru acest task. | ||
+ | </note> | ||
- | ==== Mișcarea apei ==== | + | ==== Realizarea efectului de mișcare al apei ==== |
- | Textura apei va trebui modificată în mod continuu pentru a crea un efect de mișcare al acesteia. Pentru a obține acest efect este nevoie de translatarea în funcție de timp a coordonatelor de texturare ale fragmentului. Pentru a obține timpul programului se poate folosii funcția ''Engine::GetElapsedTime()''. Astfel, noile coordonate se pot calcula ca ''vec2 new_coords = texcoord + vec2(time, 0);''. Implementarea efectului în shader este obligatorie. | + | Textura apei va trebui modificată în mod continuu pentru a crea un efect de mișcare al acesteia. Pentru a obține acest efect este nevoie de **translatarea în funcție de timp a coordonatelor de texturare**. |
+ | |||
+ | Este obligatorie implementarea acestei cerințe în shader - un efect similar se poate obține prin simpla translatare a mesh-ului în mod continuu, ceea ce este **nepermis**. | ||
+ | |||
+ | <note tip>Vă puteți folosi de ''Engine::GetElapsedTime()'' pentru a obține timpul scurs de la pornirea aplicației.</note> | ||
==== Realizarea efectului de valuri în shader ==== | ==== Realizarea efectului de valuri în shader ==== | ||
Line 72: | Line 83: | ||
Pentru a reda un efect de valuri, textura aplicată apei va trebui alterată în mod continuu în fragment shader. Rezultatul implementării voastre nu trebuie să replice în mod direct exemplul din demo, dar este necesar să se supună următoarelor reguli: | Pentru a reda un efect de valuri, textura aplicată apei va trebui alterată în mod continuu în fragment shader. Rezultatul implementării voastre nu trebuie să replice în mod direct exemplul din demo, dar este necesar să se supună următoarelor reguli: | ||
* Implementare în fragment shader | * Implementare în fragment shader | ||
- | * Ajustarea coordonatelor de texturare ale fragmentelor pentru a obține efectul dorit | + | * Folosirea unor funcții trigonometrice împreună cu poziția în lume a fragmentelor pentru a modula coordonatele de texturare |
- | * Folosirea unor funcții trigonometrice pentru a calcula o translatare în plus a coordonatelor în funcție de poziția în lumea a fragmentului | + | |
* Animație de tip continuu, așadar, necesitatea folosirii unei variabile pentru timp | * Animație de tip continuu, așadar, necesitatea folosirii unei variabile pentru timp | ||
- | Astfel, pentru a calcula translatarea necesară pentru valuri se poate folosii o formulă de genul ''vec2 wave_translation_coords = vec2(sin(world_position.x * 10) / 300f);''. | + | Pentru a înțelege mai bine conceptul puteți studia următorul snippet de cod - acesta colorează mesh-ul de apă în funcție de poziția în spațiul lume a fragmentelor. Observați faptul că aceeste coordonate (s-a considerat numai coordonata X a acestora) sunt modulate folosind o funcție trigonometrică. |
+ | |||
+ | <code cpp> | ||
+ | // GLSL code | ||
+ | // sin() outputs in range [-1;1]. Adding 1 and multiplying with 0.5 remaps result to [0;1] range (for rendering purposes). | ||
+ | vec2 modulated_coords = (vec2(sin(world_position.x * 10)) + 1) * 0.5; | ||
+ | out_color = vec4(modulated_coords.x, modulated_coords.x, modulated_coords.x, 1); | ||
+ | </code> | ||
+ | |||
+ | În imaginea de mai jos puteți observa efectul obținut: | ||
+ | |||
+ | {{ :egc:teme:2023:egc_2023_t3_wavepositioncolored.png?400 |}} | ||
+ | |||
+ | <note>Nu sunt aplicate calcule de iluminare în imaginea de mai sus.</note> | ||
+ | |||
+ | <note important>**Atenție**, această colorare este doar în scop demonstrativ! Voi va trebui să vă folosiți de acest concept **nu** pentru colorarea directă a mesh-ului, ci pentru alterarea coordonatelor de texturare ale apei.</note> | ||
- | În GIF-ul de mai jos puteți observa în partea stânga textura apei care suferă doar efectul de translație, iar în partea dreaptă un exemplu pentru translație + efectul de valuri. | + | În GIF-ul de mai jos puteți observa în partea stângă textura apei care suferă doar efectul de translație, iar în partea dreaptă un exemplu pentru translație + efectul de valuri. |
{{ :egc:teme:2023:egc_2023_t3_watertexturemodulation.gif?650 |}} | {{ :egc:teme:2023:egc_2023_t3_watertexturemodulation.gif?650 |}} | ||
Line 88: | Line 113: | ||
Iluminarea scenei se va implementa folosind 3 tipuri de surse de lumină: **punctiformă**, **direcțională** și **spotlight**. Fiecare sursă de lumină (indiferent de tipul acesteia) o să aibă o culoare specifică și trebuie să se țină cont de această culoare pentru iluminare. | Iluminarea scenei se va implementa folosind 3 tipuri de surse de lumină: **punctiformă**, **direcțională** și **spotlight**. Fiecare sursă de lumină (indiferent de tipul acesteia) o să aibă o culoare specifică și trebuie să se țină cont de această culoare pentru iluminare. | ||
- | **Lumină punctiformă:** acest tip de sursă de lumină este cel prezentat la laborator. Este necesar să se folosească acest tip de lumina pentru: | + | **Lumina punctiformă:** acest tip de sursă de lumină este cel prezentat la laborator. Este necesar să se folosească acest tip de lumină pentru: |
- | * Reflectorul farului (pe lângă lumina spotlight a acestuia) astfel încât să se ilumineze și turnul farului | + | * Reflectorul farului (pe lângă lumina spotlight a acestuia) astfel încât să se ilumineze zonele din proximitatea farului |
* Fiecare bărcuță, astfel încât să se ilumineze aceasta și apa din jurul ei. Lumina va fi atașată de bărcuță și trebuie să aibă o culoare aleatorie | * Fiecare bărcuță, astfel încât să se ilumineze aceasta și apa din jurul ei. Lumina va fi atașată de bărcuță și trebuie să aibă o culoare aleatorie | ||
Line 96: | Line 121: | ||
{{ :egc:teme:2023:egc_2023_t3_pointlightsonly.png?400 |}} | {{ :egc:teme:2023:egc_2023_t3_pointlightsonly.png?400 |}} | ||
- | **Lumină 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 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 luna 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ă - observați iluminarea pe partea stângă a farului, corespunzătoare direcției cerute. | În următoarea imagine a fost activată numai lumina direcțională - observați iluminarea pe partea stângă a farului, corespunzătoare direcției cerute. | ||
Line 102: | Line 127: | ||
{{ :egc:teme:2023:egc_2023_t3_dirlightonly.png?400 |}} | {{ :egc:teme:2023:egc_2023_t3_dirlightonly.png?400 |}} | ||
- | **Lumina de tip spotlight:** acest tip de sursă de lumină este cel prezentat la laborator. Este necesar să se folosească 2 surse de acest tip de lumină pentru far, poziționate în partea superioară a acestuia, care să se rotească în jurul farului în mod continuu. Între direcțiile celor 2 surse spotlight trebuie să fie un defazaj de 180°. De asemenea, luminile spotlight trebuie să fie colorate (detalii în secțiunea **Interfața cu utilizatorul**) | + | **Lumina de tip spotlight:** acest tip de sursă de lumină este cel prezentat la laborator. Este necesar să se folosească 2 surse de acest tip pentru far, poziționate în partea superioară a acestuia, care să se rotească în jurul farului în mod continuu. Între direcțiile celor 2 surse spotlight trebuie să fie un defazaj de 180°. De asemenea, luminile spotlight trebuie să fie colorate (detalii în secțiunea **Interfața cu utilizatorul**) |
În următorul GIF puteți observa un exemplu de implementare pentru comportamentul acestor spotlight-uri. | În următorul GIF puteți observa un exemplu de implementare pentru comportamentul acestor spotlight-uri. | ||
Line 120: | Line 145: | ||
==== Mesh-ul lunii ==== | ==== Mesh-ul lunii ==== | ||
- | Mesh-ul lunii trebuie texturat cu o imagine a lunii. Pentru a oferi o strălucire lunii (efect de glow) este necesar ca randarea acesteia să includă și o componentă emisivă de culoare albă. | + | Mesh-ul lunii trebuie texturat cu o imagine a lunii. Pentru a oferi o strălucire lunii este necesar ca randarea acesteia să includă și o componentă emisivă de culoare albă. |
===== Interfața cu utilizatorul ===== | ===== Interfața cu utilizatorul ===== | ||
Line 126: | Line 151: | ||
Interfața cu utilizatorul constă în implementarea a 3 slider-e, ce au scopul de a controla culoarea luminilor emise de către far (point și spotlight), precum și culoarea mesh-ului reflector. Fiecare slider va controla contribuția unei componete de culoare (R, G, B), iar culoarea finală va fi calculată corespunzător acestor contribuții. | Interfața cu utilizatorul constă în implementarea a 3 slider-e, ce au scopul de a controla culoarea luminilor emise de către far (point și spotlight), precum și culoarea mesh-ului reflector. Fiecare slider va controla contribuția unei componete de culoare (R, G, B), iar culoarea finală va fi calculată corespunzător acestor contribuții. | ||
- | Slider-ele pot fi construite din pătrate scalate. Este necesar ca fiecare slider să fie construit din 2 astfel de pătrate - unul pentru componenta statică a slider-ului (background-ul), celălalt pentru componenta interactivă (care se poate scala). Componenta interactivă trebuie colorată corespunzător canalului de culoare pe care o controlează. | + | **Construcție:** Slider-ele pot fi construite din pătrate scalate. Este necesar ca fiecare slider să fie construit din 2 astfel de pătrate - unul pentru componenta statică a slider-ului (background-ul), celălalt pentru componenta interactivă (care se poate scala). Componenta interactivă trebuie colorată corespunzător canalului de culoare pe care o controlează. |
- | Interacțiunea cu slider-ele se va realiza prin intermediul cursorului. La evenimentului unui click în zona din ecran corespunzătoare slider-ului, componenta scalabilă a slider-ului va urmări în fiecare frame poziția pe ecran a cursorului. | + | **Interacțiune**: Aceasta se va realiza prin intermediul a 6 taste - pentru fiecare slider se vor folosi câte 2 taste, una pentru a crește valoarea contribuției, cealaltă pentru scăderea acesteia. Partea interactivă a slider-elor se va scala corespunzător valorii contribuției. Această interacțiune trebuie să aibă loc **în fiecare frame** în care tastele sunt ținute apăsate. |
Pentru randarea slider-ului vă recomandăm următoarele (nu sunt cerințe impuse): | Pentru randarea slider-ului vă recomandăm următoarele (nu sunt cerințe impuse): | ||
* Folosirea unei camera cu proiecție ortografică - puteți folosi doar o singură cameră, randați întâi scena 3D folosind proiecția perspectivă, iar pentru slider-e o configurați folosind o proiecție ortografică | * Folosirea unei camera cu proiecție ortografică - puteți folosi doar o singură cameră, randați întâi scena 3D folosind proiecția perspectivă, iar pentru slider-e o configurați folosind o proiecție ortografică | ||
* Implementarea unui shader auxiliar doar pentru randarea slider-elor | * Implementarea unui shader auxiliar doar pentru randarea slider-elor | ||
- | |||
- | <note> | ||
- | Interacțiunea cu aceste elemente de UI, precum și efectul acestora se poate observa în videoclip-ul demo. | ||
- | </note> | ||
===== Barem ===== | ===== Barem ===== | ||
Line 147: | Line 168: | ||
* Rotație bărcuțe (fiecare cu rază diferită) în jurul insulei (5p) | * Rotație bărcuțe (fiecare cu rază diferită) în jurul insulei (5p) | ||
* Orientarea corectă a bărcuțelor în funcție de traiectoria lor (5p) | * Orientarea corectă a bărcuțelor în funcție de traiectoria lor (5p) | ||
+ | * **Efecte shader apă** (35p) | ||
+ | * Repetare textură (5p) | ||
+ | * Efect de mișcare al texturii apei (10p) | ||
+ | * Efect de valuri (20p) | ||
* **Iluminare** (40p) | * **Iluminare** (40p) | ||
* Lumină direcțională (10p) | * Lumină direcțională (10p) | ||
Line 155: | Line 180: | ||
* Implementarea celor 2 lumini, cu originea în far (10p) | * Implementarea celor 2 lumini, cu originea în far (10p) | ||
* Rotația în mod continuu a acestora (5p) | * Rotația în mod continuu a acestora (5p) | ||
- | * **Efecte shader apă** (35p) | ||
- | * Repetare textură (5p) | ||
- | * Efect de mișcare al texturii apei (10p) | ||
- | * Efect de valuri (20p) | ||
* **Interfața cu utilizatorul** (30p) | * **Interfața cu utilizatorul** (30p) | ||
* Randarea celor 3 slider-e (10p) | * Randarea celor 3 slider-e (10p) | ||
- | * Interacțiunea cu mouse-ul (10p) | + | * Interacțiunea cu slider-ele folosind tastele (10p) |
* Setarea culorii luminilor farului pe baza valorii slider-elor (10p) | * Setarea culorii luminilor farului pe baza valorii slider-elor (10p) | ||
- | ===== [WIP] Exemple de Funcționalități Bonus===== | + | ===== Exemple de Funcționalități Bonus===== |
- | todo | + | * Interacțiunea cu slider-ele folosind cursorul (exemplu în demo) |
+ | * Introducerea unor bărcuțe "polițist" cu girofar | ||
+ | * Modelarea valurilor 3D (vertex displacement) | ||
+ | * Utilizarea unei traiectorii complexe pentru deplasarea bărcuțelor | ||
+ | * Modelarea unor obstacole plutitoare | ||
+ | * Selector de culoare sub formă circulară pe modelul HSV | ||
===== Întrebări și răspunsuri ===== | ===== Întrebări și răspunsuri ===== | ||
Line 194: | Line 220: | ||
* Î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> |