This shows you the differences between two versions of the page.
|
pgapi:teme:2025:02 [2025/12/10 18:08] maria_anca.balutoiu [Prezentare rezultat] |
pgapi:teme:2025:02 [2025/12/13 13:51] (current) maria_anca.balutoiu [Descriere generală] |
||
|---|---|---|---|
| Line 2: | Line 2: | ||
| * **Responsabili:** Mihnea-Petruț-Ilie Mitrache, Andrei-Daniel Voicu, Maria Anca Baluțoiu | * **Responsabili:** Mihnea-Petruț-Ilie Mitrache, Andrei-Daniel Voicu, Maria Anca Baluțoiu | ||
| - | * **Lansare:** 12.12.2025 | + | * **Lansare:** 14.12.2025 |
| * **Termen de predare:** 18.01.2026 | * **Termen de predare:** 18.01.2026 | ||
| * **Regulament:** https://ocw.cs.pub.ro/courses/pgapi/regulament_general | * **Regulament:** https://ocw.cs.pub.ro/courses/pgapi/regulament_general | ||
| Line 9: | Line 9: | ||
| ===== Descriere generală ===== | ===== Descriere generală ===== | ||
| - | Scopul acestei teme va fi implementarea unui efect de blur de profunzime (''Depth of Field / Bokeh Blur'') aplicat unei imagini 2D, în care zona de focus va fi controlabilă interactiv de către utilizator. | + | Scopul acestei teme va fi implementarea unui efect de blur de profunzime (''Depth of Field / Bokeh Blur'') aplicat unei imagini 2D ([[https://www.ea.com/frostbite/news/circular-separable-convolution-depth-of-field|similar cu cel propus de cei de la Electronic Arts]]), în care zona de focus va fi controlabilă interactiv de către utilizator. |
| + | |||
| + | Puteți studia în următorul videoclip o posibilă implementare a cerințelor. | ||
| + | |||
| + | <html> | ||
| + | <p style="text-align:center;margin:auto;"> | ||
| + | <iframe width="500" height="315" src="https://www.youtube.com/embed/CfF4i2_glRQ?vq=hd720" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> | ||
| + | </p> | ||
| + | </html> | ||
| Efectul urmărit este inspirat din tehnicile folosite în motoare grafice moderne (de exemplu, Frostbite), unde zonele din afara planului de focus sunt estompate folosind kernel-uri de blur gaussian (sau combinații de mai multe gaussiene), pentru a simula comportamentul unei lentile reale. | Efectul urmărit este inspirat din tehnicile folosite în motoare grafice moderne (de exemplu, Frostbite), unde zonele din afara planului de focus sunt estompate folosind kernel-uri de blur gaussian (sau combinații de mai multe gaussiene), pentru a simula comportamentul unei lentile reale. | ||
| Line 21: | Line 29: | ||
| Efectul final trebuie să arate ca un **blur radial**: zona din jurul cursorului este clară, iar blurul crește progresiv odată cu distanța față de aceasta. | Efectul final trebuie să arate ca un **blur radial**: zona din jurul cursorului este clară, iar blurul crește progresiv odată cu distanța față de aceasta. | ||
| - | {{ :pgapi:teme:2024:bokeh_examples.png?600 |Exemple de rezultate pentru efectul de Interactive Bokeh Blur}} | + | {{ :pgapi:teme:2025:exempleblur.png?500 |}} |
| ===== Arhitectura generală ===== | ===== Arhitectura generală ===== | ||
| - | + | În cadrul temei, puteți alege dacă doriți să implementați pe CPU sau pe GPU (considerat bonus). În cazul implementării pe GPU, pentru a obține efectul dorit se vor folosi două treceri (2 pass-uri) de procesare pe GPU, pe un ''quad'' randat pe tot ecranul, astfel: | |
| - | Pentru a obține efectul dorit se vor folosi două treceri (2 pass-uri) de procesare pe GPU, pe un ''quad'' randat pe tot ecranul, astfel: | + | |
| - **Primul pass:** blur gaussian orizontal și salvarea valorii de blur; | - **Primul pass:** blur gaussian orizontal și salvarea valorii de blur; | ||
| Line 33: | Line 40: | ||
| Pașii principali ai algoritmului sunt următorii: | Pașii principali ai algoritmului sunt următorii: | ||
| - | - Se încărcă imaginea inițială ca textură. | + | - Se încărcă imaginea inițială (ca textură în cazul implementării pe GPU). |
| - | - Primul pass: | + | - Prima etapă de procesare (primul pass în cazul implementării pe GPU): |
| * Se calculează, pentru fiecare pixel, distanța până la punctul de focus; | * Se calculează, pentru fiecare pixel, distanța până la punctul de focus; | ||
| * Se determină „cantitatea de blur” (''blurAmount'') pe baza acestei distanțe; | * Se determină „cantitatea de blur” (''blurAmount'') pe baza acestei distanțe; | ||
| * Se aplică un blur gaussian orizontal, cu o rază care depinde de ''blurAmount''; | * Se aplică un blur gaussian orizontal, cu o rază care depinde de ''blurAmount''; | ||
| - | * Se scrie în două texturi: | + | * Se procesează 2 imagini (în cazul implementării pe GPU, se scrie în două texturi): |
| * **textura 0**: rezultatul blurului orizontal; | * **textura 0**: rezultatul blurului orizontal; | ||
| - | * **textura 1**: culoarea originală + ''blurAmount'' stocat în canalul alfa. | + | * **textura 1**: culoarea originală + ''blurAmount'' stocat în canalul alfa (normalizat). |
| - | - Al doilea pass: | + | - A doua etapă de procesare (al doilea pass în cazul implementării pe GPU): |
| - | * Se citește ''blurAmount'' din canalul alfa al texturii cu culoarea originală; | + | * Se citește ''blurAmount'' din canalul alfa al imaginii (texturii) cu culoarea originală; |
| - | * Se calculează o nouă rază de blur în funcție de ''blurAmount''; | + | * Se utilizează''blurAmount'' pentru a recalcula dimensiunea măștii de filtrare; |
| * Se aplică un blur gaussian vertical peste rezultatul orizontal; | * Se aplică un blur gaussian vertical peste rezultatul orizontal; | ||
| - | * Se scrie rezultatul final într-o textură de output. | + | * Se scrie rezultatul final într-o imagine (textură) de output. |
| - Afișare: | - Afișare: | ||
| * Se afișează fie imaginea originală, fie un rezultat intermediar, fie imaginea procesată; | * Se afișează fie imaginea originală, fie un rezultat intermediar, fie imaginea procesată; | ||
| * Se desenează cercuri concentrice în jurul punctului de focus, pentru a marca vizual zona clară a imaginii. | * Se desenează cercuri concentrice în jurul punctului de focus, pentru a marca vizual zona clară a imaginii. | ||
| - | {{ :pgapi:teme:2024:bokeh_pipeline.png?600 |Schema de principiu a celor două pass-uri de procesare}} | + | |
| + | {{ :pgapi:teme:2025:pas_i.png?500 |}} | ||
| + | |||
| + | |||
| + | {{ :pgapi:teme:2025:pas_ii_.png?500 |}} | ||
| + | |||
| + | <note tip>Puteți începe cu oricare dintre cele două tipuri de blur. Varianta de mai sus pornește cu filtrul de blur orizontal.</note> | ||
| ===== Calculul cantității de blur ===== | ===== Calculul cantității de blur ===== | ||
| Line 84: | Line 97: | ||
| ===== Filtru de netezire separabil (blur gaussian) ===== | ===== Filtru de netezire separabil (blur gaussian) ===== | ||
| - | Pentru blur se folosește un filtru gaussian **separabil**: | + | Pentru blur se folosește un filtru gaussian **separabil** ([[https://en.m.wikipedia.org/wiki/Separable_filter|ca aici]]): |
| - | * într-un pass se aplică doar pe orizontală (axa X); | + | * mai întâi (în cazul implementării pe GPU, în primul pass), se aplică doar pe orizontală (axa X); |
| - | * în celălalt pass se aplică doar pe verticală (axa Y). | + | * apoi (în pass-ul al doilea în cazul implementării pe GPU) se aplică doar pe verticală (axa Y). |
| Aceasta reduce complexitatea de la $O(N^2)$ la $O(2N)$ pentru un kernel de dimensiune $N$. | Aceasta reduce complexitatea de la $O(N^2)$ la $O(2N)$ pentru un kernel de dimensiune $N$. | ||
| Line 101: | Line 114: | ||
| În implementare se poate folosi un singur kernel gaussian sau o combinație de mai multe gaussiene cu $\sigma$ diferite și ponderi diferite, pentru un efect de bokeh mai interesant (de exemplu: 3 gaussiene cu $\sigma$ mic, mediu și mare). | În implementare se poate folosi un singur kernel gaussian sau o combinație de mai multe gaussiene cu $\sigma$ diferite și ponderi diferite, pentru un efect de bokeh mai interesant (de exemplu: 3 gaussiene cu $\sigma$ mic, mediu și mare). | ||
| + | |||
| + | |||
| + | Începem cu imaginea originală: | ||
| + | {{ :pgapi:teme:2024:earth.png?600 |}} | ||
| + | |||
| + | Primul pas este efectuarea unei neteziri pe orizontală. Fiecare pixel va fi egal cu media aritmetică a pixelului și a vecinilor pe aceeași linie cu pixelul. | ||
| + | |||
| + | Rezultatul este acesta: | ||
| + | {{ :pgapi:teme:2024:earth_blur_horz.png?600 |}} | ||
| + | |||
| + | Al doilea pas este efectuarea a unei neteziri pe verticală. Fiecare pixel va fi egal cu media aritmetică a pixelului și a vecinilor pe aceeași coloană cu pixelul. | ||
| + | |||
| + | Rezultatul este acesta: | ||
| + | {{ :pgapi:teme:2024:earth_blur_vert.png?600 |}} | ||
| ===== Model de bokeh / blur radial ===== | ===== Model de bokeh / blur radial ===== | ||
| Line 121: | Line 148: | ||
| * Dacă testul este adevărat, acel pixel este colorat alb (sau altă culoare), obținându-se cercuri de ghidaj. | * Dacă testul este adevărat, acel pixel este colorat alb (sau altă culoare), obținându-se cercuri de ghidaj. | ||
| - | {{ :pgapi:teme:2024:bokeh_focus_rings.png?600 |Exemplu de reprezentare a zonei de focus cu cercuri concentrice}} | + | {{ :pgapi:teme:2025:circlesgif.gif?500 |}} |
| ===== Prezentare rezultat ===== | ===== Prezentare rezultat ===== | ||
| Line 140: | Line 167: | ||
| <note important> | <note important> | ||
| - | * Tema trebuie implementată în **C/C++** pentru partea de aplicație și **GLSL** pentru shadere. | + | * Tema trebuie implementată în limbajul de programare **C/C++**, în situația în care se realizează o rezolvare ce se execută pe unitatea centrală de procesare, CPU, sau într-un limbaj specializat pentru implementarea pe procesorul grafic, precum **GLSL**. |
| * **NU** este permisă utilizarea de biblioteci de procesare de imagine pentru implementarea efectului de blur. Efectul trebuie implementat în shaderele voastre (GLSL). | * **NU** este permisă utilizarea de biblioteci de procesare de imagine pentru implementarea efectului de blur. Efectul trebuie implementat în shaderele voastre (GLSL). | ||
| * Se pot folosi biblioteci pentru: | * Se pot folosi biblioteci pentru: | ||
| Line 163: | Line 190: | ||
| ===== Bonusuri posibile ===== | ===== Bonusuri posibile ===== | ||
| - | * Utilizarea unei combinații de mai multe gaussiene pentru kernel (mixtură de gaussiene) pentru un efect de bokeh mai realist (10-20p) | + | * Implementare pe GPU (25p) |
| + | * Utilizarea unei combinații de mai multe gaussiene pentru kernel pentru un efect de bokeh mai realist (10-20p) | ||
| * Optimizări suplimentare inspirate din tehnici de tip ''Circular Separable Convolution Depth of Field'' (10-20p) | * Optimizări suplimentare inspirate din tehnici de tip ''Circular Separable Convolution Depth of Field'' (10-20p) | ||
| * Kernel-uri circulare; | * Kernel-uri circulare; | ||