This is an old revision of the document!


%%%2121!!!+++CUTHERE+++!!!2121%%%
  • Responsabili: Andrei Lăpușteanu, Vlad-Matei Drăghici, Mihnea-Petruţ-Ilie Mitrache
  • Lansare: 14 decembrie 2025
  • Termen de predare: 18 ianuarie 2026, ora 23:59
  • Regulament: Regulament general
  • Notă: Această temă este considerată temă suplimentară
  • Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!

În cadrul acestei teme puteți opta pentru a lucra în echipe de maxim 2 studenți!

  • Cerințele sunt aceleași atât pentru o implementare în mod individual cât și în echipă
  • În cazul lucrului în echipă, în timpul prezentării temei va trebui să prezentați în mod diferențiat contribuția fiecăruia (să știe și să prezinte fiecare student ce a implementat)

  • Terenul: Format dintr-un plan texturat
  • Copacii: Formați din primitive (construcția acestora este specificată în capitolele următoare)
  • Licuricii: Formați din sfere mici cu proprietăți emisive
  • Turnul de observație: Format din primitive (construcția acestuia este specificată în capitolele următoare)
  1. Stâlpi de susținere (4 paralelipede care trec prin platformă și ajung la acoperiș)
  2. Platformă (paralelipiped)
  3. Acoperiș (con turtit pe înălțime)
  4. Proiectoare pentru lumini (2 conuri)

Puteți propune alte variante de geometrie. Spre exemplu să realizați elemente diferite pentru susținerea bazei și a acoperișului. Simplificări ale variantei propuse nu vor aduce punctajul total.

Primitiva de tip con nu se regăsește în framework. Dacă doriți s-o utilizați, aceasta se poate descărca de aici cone.zip

  1. Trunchi (cilindru)
  2. Frunziș (minim 6 paralelipipede)

Primitiva de tip cilindru nu se regăsește în framework. Dacă doriți s-o utilizați, aceasta se poate descărca de aici cylinder.zip

$$ t = \frac{y}{TREE\_HEIGHT}\\ scale = 1 - t\\ x_{final} = x_{original} \cdot scale\\ z_{final} = z_{original} \cdot scale $$

  • Înălțimea normalizată a vârfului (0 la bază, 1 la vârf)
  • Frecvența și faza oscilației (diferite pentru fiecare copac pentru variație vizuală)
  • Amplitudinea maximă a deplasării

$$ t = \frac{y}{TREE\_HEIGHT}\\ wave = \sin(Time \cdot BendFrequency + t \cdot 0.5 + BendPhase)\\ offset = wave \cdot BendStrength \cdot t\\ x_{new} = x_{original} + offset $$

Amplitudine:

$$ Trunchi: offset = wave \cdot A_{trunchi} \cdot t = wave \cdot 0.0 \cdot t = 0 \\ Frunze\_Jos: offset = wave \cdot A_{mic} \cdot t\\ Frunze\_Mijloc: offset = wave \cdot A_{mediu} \cdot t\\ Frunze\_Varf: offset = wave \cdot A_{mare} \cdot t $$

  • Trunchiul – textură de lemn/scoarță
  • Frunzișul – textură de frunze/vegetație

Nu uitați că este necesară setarea wrapping_mode-ului texturii cu GL_REPEAT. De asemenea, vă recomandăm utilizarea unei texturi de tip “seamless” pentru acest task.

  • Rază orbitală – distanța față de centrul orbitei (camera sau turnul)
  • Viteză unghiulară – viteza de rotație pe orbită
  • Fază inițială – poziția de start pe cerc
  • Oscilație verticală – mișcare sinusoidală pe axa Y pentru un efect mai natural

\[ x = C_x + R \cdot \cos(\omega t + \phi) \\ z = C_z + R \cdot \sin(\omega t + \phi) \\ y = C_y + h_0 + A \cdot \sin(\omega_v t + \phi_v) \]

\((C_x, C_y, C_z)\)\(R\)\(A\)

  • \(\vec{P}\) – poziția fragmentului în spațiul lumii
  • \(\vec{C}\) – poziția camerei
  • \(d_{\text{max}}\) – distanța maximă de vizibilitate

\[ d = \|\vec{P} - \vec{C}\| \]

\([0, 1]\)

\[ f_{\text{fog}} = \text{clamp}\left(\frac{d}{d_{\text{max}}}, 0, 1\right) \]

mix

\[ \vec{C}_{\text{final}} = \text{mix}(\vec{C}_{\text{obiect}}, \vec{C}_{\text{fog}}, f_{\text{fog}}) \]

\(\vec{C}_{\text{obiect}}\)după iluminare și texturare\(\vec{C}_{\text{fog}}\)

Pentru un efect realistic, setați culoarea de ștergere a ecranului să fie acceași cu cea a ceții.

punctiformăspotlight

Iluminarea trebuie să fie implementată folosind modelul de shading Phong, precum și modelul de calcul al reflexiei luminii Phong.

  • Se va deplasa odată cu licuriciul
  • Va avea culoare din nuanțe de galben-verde (caracteristic licuricilor)
  • Va avea intensitate variată pentru fiecare licurici

==== Lumini Spotlight ====

Spotlight-urile emit lumină într-un con limitat, definit prin poziție, direcție și unghi de cutoff (\(\alpha\)). Un fragment este iluminat doar dacă se află în interiorul conului, iar intensitatea luminii scade gradual către margini. Implementarea luminii de tip spotlight se bazează pe cea pe care ați realizat-o în Laboratorul 08.

==== Light Cookies (Gobo Lights) ====

Light cookies sunt texturi proiectate prin conul de lumină al unui spotlight pentru a crea pattern-uri de umbră și lumină.

În iluminatul fizic (teatru, cinematografie) există două concepte înrudite:

  • Gobo (termen provenit din “goes before optics”) – șablon metalic plasat în interiorul sau foarte aproape de sursa de lumină (produce margini clare, pattern-uri precise)
  • Cookie (termen provenit din cucoloris) – panou cu decupaje plasat mai departe de sursă (produce margini difuze, efecte mai naturale)

În grafica pe calculator, cei doi termeni sunt folosiți interschimbabil – ambii se referă la aplicarea unei texturi (textură alpha sau RGB) asupra unei lumini pentru a modula intensitatea și/sau culoarea acesteia.

Mai jos puteți observa câteva example de light cookies din diverse aplicații grafice.

==== Proiecția unei texturi de tip light cookie folosind o lumină spotlight ====

Pentru un spotlight, putem proiecta o textură (light cookie) pe fragmentele iluminate, similar unei proiecții tip perspectivă. În această secțiune sunt prezentați pașii matematici necesari pentru a determina coordonatele de textură corespunzătoare fiecărui fragment.

În figura următoare puteți observa o diagramă ce prezintă notațiile necesare pentru a calcula proiecția texturii de tip light cookie. Reveniți la diagramă când este necesar pentru a face corespondența cu derivarea matematică prezentată în subsecțiunile ce urmează.

Calculele prezentate în continuare trebuie realizate toate în Fragment Shader! Ordinea de implementare pentru luminile spotlight este:

  • Implementare iluminare spotlight “clasică” (calcul bazat pe cut_off, spot_light, spot_light_limit, light_att_factor pentru a obține contribuția difuză și speculară a luminii - contribuția de bază)
  • Implementare efect light cookie
  • Modularea contribuției de bază cu rezultatul efectului de light cookie

Considerăm:

  • poziția sursei de lumină \(\vec{L}\)
  • un punct de pe suprafața iluminată \(\vec{X}\)

Definim vectorul dintre sursa de lumină și punctul iluminat:

\[ \vec{v} = \vec{X} - \vec{L} \]

=== Sistemul de coordonate al spotlight-ului ===

Pentru a putea exprima punctele în raport cu direcția spotului, definim un sistem local de coordonate al spotlight-ului, format din trei vectori ortogonali (forward, right, up), care definesc un sistem de coordonate ortonormat \((\hat{x}, \hat{y}, \hat{z})\).

Direcția spotlight-ului este dată de vectorul \(\vec{d}_{light}\) (corespunzător variabilei light_direction din shader-ul laboratorului 8). Acest vector este considerat deja normalizat și definește axa \(\hat{z}\) (forward) a sistemului local de coordonate al spotlight-ului.

Pentru a construi o bază ortonormată completă, avem nevoie de un vector arbitrar \(\vec{a}\) care să nu fie paralel cu \(\hat{z}\). Putem defini:

\[ \vec{a} = \begin{cases} (0, 1, 0), & \text{daca } | \hat{z} \cdot (0, 1, 0)| \neq 1 \\ (1, 0, 0), & \text{altfel} \end{cases} \]

Cu alte cuvinte, găsim \(\vec{a}\) astfel încât produsul scalar dintre acesta și \(\hat{z}\) să fie diferit de 1 (să nu fie paraleli).

La implementare, verificarea \(|\hat{z} \cdot (0, 1, 0)| \neq 1\) trebuie făcută cu o toleranță numerică pentru a evita erorile de precizie în virgulă mobilă.

Axa \(\hat{x}\) (right) a spotlight-ului se obține prin produs vectorial între vectorul de referință și axa \(\hat{z}\) (forward), urmat de normalizare:

\[ \hat{x} = \frac{\vec{a} \times \hat{z}}{\|\vec{a} \times \hat{z}\|} \]

Axa \(\hat{y}\) (up) este apoi determinată ca produs vectorial între două axe unitare ortogonale:

\[ \hat{y} = \hat{z} \times \hat{x} \]

Obținem astfel baza ortonormată \((\hat{x}, \hat{y}, \hat{z})\) ce reprezintă sistemul de coordonate al spotlight-ului.

=== Punct în spațiul spotlight-ului ===

Pentru a exprima poziția punctului \(\vec{X}\) de coordonate \((x, y, z)\) în sistemul local al spotlight-ului, proiectăm vectorul \(\vec{v}\) pe axele noului sistem de coordonate:

\[ x = \vec{v} \cdot \hat{x} \\ y = \vec{v} \cdot \hat{y} \\ z = \vec{v} \cdot \hat{z} \]

Coordonata \(z\) măsoară distanța punctului de-a lungul axei principale a spotului.

=== Proiecția pe planul de referință \(z = 1\) ===

Pentru proiecția texturii de tip light cookie, considerăm un plan de referință perpendicular pe axa \(\hat{z}\), situat la coordonata:

\[ z = 1 \]

Coordonatele punctului proiectat pe acest plan se obțin printr-o împărțire perspectivă:

\[ \vec{p} = \begin{pmatrix} \dfrac{x}{z} \\ \dfrac{y}{z} \end{pmatrix} \]

Punctul \(\vec{p}\) reprezintă intersecția razei de lumină cu planul de proiecție.

=== Normalizare în funcție de unghiul spotului ===

Fie \(\alpha\) unghiul de deschidere al spotului. La coordonata \(z = 1\), raza conului este:

\[ R = \tan(\alpha) \]

Pentru a normaliza coordonatele proiectate astfel încât interiorul spotului să corespundă domeniului \([-1, 1]\), împărțim coordonatele lui \(\vec{p}\) la această rază:

\[ \vec{n} = \dfrac{1}{\tan(\alpha)} \, \vec{p} = \begin{pmatrix} \dfrac{x}{z \tan(\alpha)} \\ \dfrac{y}{z \tan(\alpha)} \end{pmatrix} \]

=== Maparea către coordonate de textură ===

Coordonatele normalizate \(\vec{n}\) sunt în domeniul \([-1, 1]\). Texturile sunt adresate în domeniul \([0, 1]\), așadar facem o mapare liniară:

\[ \mathbf{t} = (u, v) = \dfrac{\vec{n}}{2} + \dfrac{1}{2} \]

unde \(\mathbf{t}\) reprezintă coordonatele de textură (UV) folosite pentru eșantionare.

=== Eșantionarea texturii light cookie ===

Coordonatele \(\mathbf{t} = (u, v)\) sunt folosite pentru a eșantiona textura light cookie, obținând culoarea în punctul respectiv:

\[ \vec{c} = (c_R, c_G, c_B) \]

Valoarea \(\vec{c}\) este utilizată pentru a modula contribuția luminii spotului asupra fragmentului, pe fiecare canal RGB separat. Mai concret, această eșantionare se realizeză în GLSL folosind funcția texture2D:

c = texture2D(cookieTexture, vec2(u, v)).rgb

===== Barem [150p] =====

  • Construcția scenei virtuale [65p]
    • Copacii [25p]
      • Asamblarea componentelor (trunchi + straturi frunziș) [7.5p]
      • Deformarea frunzișului în Vertex Shader (efect vânt) [10p]
      • Texturarea copacilor [5p]
      • Plasarea a minim 5 copaci în scenă [2.5p]
    • Terenul [10p]
      • Desenarea terenului (plan) [2.5p]
      • Textuarea cu repetare [7.5p]
    • Turnul de observație [15p]
      • Asamblarea componentelor [10p]
      • Texturarea componentelor [5p]
    • Licuricii [15p]
      • Desenarea licuricilor cu un shader emisiv [5p]
      • Logica de mișcare a licuricilor (orbitare cu oscilație) [10p]
  • Efectul de ceață [15p]
    • Implementarea efectului de ceață pentru toate obiectele scenei în Fragment Shader [15p]
  • Iluminarea [70p]
    • Lumini punctiforme (pentru licurici) [20p]
      • Câte o lumină de culoare aleatorie pentru fiecare licurici [15p]
      • Deplasarea luminii odată cu licuriciul [5p]
    • Lumini spotlight [50p]
      • Implementarea a minim 2 lumini tip spotlight [10p]
      • Proiecția a cel puțin unei texturi folosind light cookies [40p]

===== Exemple de Funcționalități Bonus =====

  • Rotația continuă a spotlight-ului în jurul turnului (similar unui far)
  • Mai multe spotlight-uri cu light cookie-uri diferite pentru fiecare
  • Efect de pulsație a intensității emisive și a luminii punctiforme pentru fiecare licurici
  • Efect Fresnel pentru licurici (strălucire accentuată la margini)
  • Generarea aleatoare a poziției și dimensiunii copacilor la fiecare rulare
  • Animație pentru light cookie (rotire, scalare sau tranziție între texturi)
  • Implementarea a unui model de ceață mai avansat (cu atenuare exponențială)
  • Variere aleatoare a culorii licuricilor (nuanțe diferite de galben-verde)

===== Întrebări și răspunsuri =====

Pentru întrebări vom folosi forumurile de pe Moodle. Orice nu este menționat în temă este la latitudinea fiecărui student!

===== Notare =====

Baremul este orientativ. Fiecare asistent are o anumită libertate în evaluarea temelor (de exemplu, să dea punctaj parțial pentru implementarea incompletă a unei funcționalități sau să scadă pentru hard coding). Același lucru este valabil atât pentru funcționalitățile obligatorii, cât și pentru bonusuri.

Tema trebuie încărcată pe Moodle. Pentru a fi punctată, tema trebuie prezentată la laborator. Vor exista laboratoare speciale de prezentare a temelor (care vor fi anunțate).

===== Indicații suplimentare =====

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

Pentru implementarea temei, în folderul src/lab_m1 puteți crea un nou folder, de exemplu Tema3, cu fișierele Tema3.cpp și Tema3.h (pentru implementare POO, este indicat să aveți și alte fișiere). Pentru a vedea fișierele nou create în Visual Studio în Solution Explorer, apăsați click dreapta pe filtrul lab_m1 și selectați Add→New Filter. După ce creați un nou filtru, de exemplu Tema3, dați click dreapta și selectați Add→Existing Item. Astfel adăugați toate fișierele din folderul nou creat. În fișierul lab_list.h trebuie adăugată și calea către header-ul temei. De exemplu: #include “lab_m1/Tema3/Tema3.h”

===== Arhivarea Proiectului =====

  • În mod normal arhiva trebuie să conțină toate resursele necesare compilării și rulării
  • Înainte de a face arhiva asigurați-vă că ați curățat proiectul Visual Studio:
    • Click dreapta pe proiect în Solution ExplorerClean Solution
    • Ștergeți folderul /build/.vs (dacă nu îl vedeți, este posibil să fie ascuns)
  • Î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.

</hidden>

egc/teme/2025/03.1765721005.txt.gz · Last modified: 2025/12/14 16:03 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