Differences

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

Link to this comparison view

spg:laboratoare:05 [2018/10/26 09:54]
alexandru.gradinaru
spg:laboratoare:05 [2024/04/10 17:33] (current)
robert.caragicu Corectare dezacord
Line 1: Line 1:
-===== Laboratorul 05=====+===== Laboratorul 05 =====
  
-===== Sisteme de particule ​=====+===== Deferred Rendering ​=====
  
 ==== Introducere ==== ==== Introducere ====
  
-Sistemele de particule au fost introduse in grafica cu principalul scop de reprezenta diferite ​obiecte ​ce nu pot fi reprezentate eficient ​prin geometrie opacaObiectele de tip fuzzy, obiectele in care lumina sufera procese de difuzie si diferite fenomene naturale sunt toate implementabile cu mare usurinta prin utilizarea sistemelor de particule.+Pentru ​desena ​obiecte ​iluminate 3D metoda studiată până acum este prin aplicarea directă a calculelor de iluminare (iluminare în vertex sau fragment shader) pentru a determina culorile pixelilor suprafețelor desenateAceastă tehnică se numește forward rendering.
  
-Totusi, datorita lipsei ​de capacitate ​de reprezentare a unei singure particule, ​pentru ​a reprezenta aceste obiecte este nevoie ​de un numar foarte mare de particule, de multe ori de ordinul zecilor si chiar sutelor de mii. De aceea este vital ca particulele sa fie implementate cat mai eficient.+Tehnica forward rendering nu se scalează bine când sunt multe surse de lumină deoarece se realizează calculele ​de iluminare și pentru ​pixelii unor suprafețe care sunt pe urmă obturați ​de pixelii altor suprafețe care sunt mai apropiați ​de observator.
  
-==== Shader Storage Buffer Objects ====+Pentru multe surse de lumină este avantajos să realizăm calculele de iluminare doar pentru pixelii care râmăn afișați în final pe ecran.
  
-Pentru a implementa eficient particulele vom folosi un nou tip de buffer. Shader storage buffer objects(SSBO-uri) sunt niste tipuri ​de buffere specifice Shader Model 5 (OpenGL 4.3) ce ofera flexbilitate foarte mare algoritmilor prin faptul ca permit IO direct in shadere (desi exista restrictii).+Deferred Rendering este o tehnică avansată, extensibilă si versatilă ​de sinteză în timp real de imagini ale obiectelor dintr-o scenă 3D. Cu un nume sugestiv, '​intârziat'​ sau '​amânat',​ tehnica se bazează pe desenarea ​de informație a geometriei din fiecare pixel(poziție in spațiul lume, vectorul normal în spațiul lume, constanta difuză, constanta speculară, strălucirea etc.) în texturi separate într-un prim pas, amânând procesul de iluminare pentru un pas urmator. Astfel când începe procesul de iluminare se vor folosi informațiile pixelilor celor mai apropiați de observator.
  
-Acestea ​sunt construite ca orice alt buffer cu:+==== Forward Rendering ==== 
 +In forward rendering culoarea finală a unui pixel se obține prin contribuția fiecărui fragment afișat in acel pixel, iar pentru culoarea fragmentelor se evaluează contribuția de la fiecare lumină din scenă. Din cauza aceasta, ​sunt evaluate fragmente ce vor fi acoperite ulterior sau se calculează contribuția neglijabilă a unei lumini îndepărtate.
  
-<code cpp> +==== Deferred Rendering ==== 
-glGenBuffers(1&​buf);​ +In deferred renderingecuația de iluminare nu se mai execută pentru fiecare combinație posibilă ​(obiectlumina), ci doar pentru luminile ce garantat au o contribuție ne-neglijabila.
-glBindBuffer(GL_SHADER_STORAGE_BUFFERbuf)+
-glBufferData(GL_SHADER_STORAGE_BUFFERdata.size()*sizeof(Data),​ &​data[0],​ GL_STATIC_DRAW ); +
-</​code>​+
  
-Diferenta cheie fata de celelalte buffere este ca SSBO-urile (Shader Storage Buffer Objectssunt legabile la puncte ​de legatura indexateastfel: +Acest lucru se face in 3 etape: 
-<code cpp> +  ​GEOMETRY PASS: evaluarea informațiilor geometrice si texturale per pixel 
-glBindBufferBase(GL_SHADER_STORAGE_BUFFER,​0buf)+  - LIGHT ACCUMULATION PASS: folosind functia de blend (GL_ONE, GL_ONE), se acumulează într-o textură rezultatul calculului ​de iluminare pentru fiecare luminăutilizând informațiile geometrice randate în G-buffer la pasul 1. 
-</​code>​+  - FINAL(COMPOSITION) PASS: se evaluează culoarea finală a pixelului ca funcție de iluminarea acumulată la pasul anterior și de informațiile texturale(și poate și geometricee.g. rim light etc.)
  
-Astfel, pe fiecare punct de legatura (GL_SHADER_STORAGE_BUFFER),​ pot exista mai multe obiecte legate. In shader legatura se face in modul urmator: +=== Geometry Buffer ===
-<​code>​ +
-struct particle{ +
- vec4 position; +
- vec4 speed; +
- vec4 iposition;​ +
- vec4 ispeed; +
-};+
  
-layout(std140,binding=0) ​buffer ​particles{ +Pentru a implementa deferred renderingvom folosi un frame buffer ​mare, denumit Geometry Buffer, sau G-Buffer. Acesta are atașate mai multe render textures utilizând GL_COLOR_ATTACHMENT_i. 
- particle data[]; +{{:​spg:​laboratoare:​g-buffer.png?​500|}}
-}+
-</​code>​+
  
-Intai este definit tipul de structura tinut in SSBO iar apoi se definiste legatura prin layout. Pentru a accesa acest buffer se poate folosi: +=== Geometry Pass === 
-<​code>​ +In această etapă sunt completate urmatoarele render targets din G-buffer: 
-vec3 pos data[gl_VertexID].position.xyz;​ +  * adâncime(se face automat) 
-vec3 spd data[gl_VertexID].speed.xyz;​ +  * poziție 
-</​code>​ +  * normală 
-Pentru sincronizare,​ pe partea de CPU se foloseste: +  * culoare
-<​code>​ +
-glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);​ +
-</​code>​+
  
-==== Constructie ====+=== Light Accumulation Pass === 
 +In această etapă sunt completate intrările din G-buffer pentru acumularea de lumină.
  
-Un sistem de particule este construit din doua componenteun set de date ce reprezinta o stare initiala sau ciclica si un set de reguli urmate de toate particulele. Din punct de vedere al redarii vizuale particulele urmeaza urmatorul proces: +Pentru a calcula intersecția intre obiecte și lumini vom folosi obiecte geometrice aferente luminilorsfera cu rază egala cu distanța maximă ​de influență pentru lumina omnidirectionalăcon cu sferă în baza pentru ​spot light(nu e implementat ​in laborator).
-  - Sunt trimise initial doar ca puncte catre banda grafica, fiecare din particule continand informatii de tipul pozitie curenta, viteza curenta, samd +
-  - In vertex shader sunt calculate noile pozitii si viteze, pentru ​fiecare particula. Rezultatele sunt scrise inapoi ​in buffer, direct din shader. +
-  - Apoi in geometry shader se efectueaza o expansiune, transformand punctul intrat in geometrie cu coordonate de texturare. Acest lucru se face exact ca imaginea urmatoare, de obiecei dupa aplicarea transformarii de vizualizare. +
-  - In fragment shader se textureaza/​coloreaza.+
  
-{{ :​spg:​laboratoare:​particle.png?​direct&​300 |}}+Pentru fiecare fragment de obiect ce reprezintă o lumină se încarcă poziția si normala din G-buffer și se evaluează ecuația de iluminare. Rezultatul este acumulat in bufferul de acumulare din G-buffer.
  
-<​note> ​  +=== Final Pass ===
-  * particulele sunt in general limitate de bandwidth, cu cat sunt mai multe cu atat sunt mai multe fragmente ce fac citiri din texturi. +
-  * In poza cu laboratorul rezolvat fiecare particula urmareste o ecuatie de aruncare +
-  * Daca nu aveti o placa cu Shader Model 5 puteti utiliza transform feedback, un tutorial ok gasiti aici: http://​ogldev.atspace.co.uk/​www/​tutorial28/​tutorial28.html ​ . Fata de varianta cu SSBO exista o serie de dezavantaje notabile. +
-  * Daca doriti sa comunicati intre invocari de shader trebuie sa aveti un mecanism de sincronizare sau un algoritm in care nu exista race-uri.  +
-  * Exista mai multe layouturi ca std140, packed sau std430. Mai multe puteti citi in specificatia OpenGL sau pe scurt in reference: https://​www.opengl.org/​sdk/​docs/​man/​ +
-</​note> ​+
  
 +In aceasta etapă se calculează rezultatul final per pixel. Culoarea nu se scrie in G-buffer, ci direct in framebuffer-ul default (cel al ferestrei grafice) sau în altul pregatit pentru postprocesare. Se combină culoarea pixelului cu iluminarea calculată și cu lumina ambientală.
  
-==== Cerinte laborator ====+{{:​spg:​laboratoare:​deferred.png?​735|}}
  
-  - Descarcati [[https://​github.com/​UPB-Graphics/​SPG-Framework/​archive/​master.zip|framework-ul de laborator]] 
-  - Completati laboratorul cu cerintele 
  
 +==== Avantaje ====
 +  - Desenarea informațiilor geometrice este eficientă deoarece nu se fac calcule de iluminare. Astfel se determină rapid pixelii cei mai apropiați de observator.
 +  - Pentru sursele de lumină de intensitate mică se vor realiza calculele de iluminare într-o zonă restrânsă pe ecran. Astfel se evită calcularea contribuției fiecărei surse de lumină pentru fiecare pixel de pe ecran.
 +  - Extensibilitatea,​ facilitează compoziția cu diverse etape de postprocesare ale informațiilor vizuale(de exemplu detecția contururilor folosind textura de normale și/sau textura de adâncime; efecte de bloom sau strălucire etc.)
 +  - Nu mai este necesară scrierea de fragment shadere care să primească ca variabile de tip uniform o listă cu sursele de lumină. În pasul de iluminare pentru fiecare sursă de lumină se folosește un shader care tratează doar acea sursă de lumină.
 +  - Având N obiecte și L surse de lumină complexitatea tehnicii deferred este O(N + L), în timp ce complexitatea forward rendering este O(N * L). De ce? Se separă buclele iterative peste mulțimea de lumini si mulțimea de obiecte din scenă:
  
-<​hidden>​ + Forward: 
-Cerinte+ for (obiect in obiecte): 
 + for (lumina in lumini): 
 + calculeaza_iluminarea(lumina,​ obiect)
  
-  * Implementare particule+ Deferred:​ 
 + for (obiect in obiecte): 
 + deseneaza(obiect,​ Gbuffer) 
 + for (lumina in lumini): 
 + deseneaza(lumina)
  
-</hidden>+==== Dezavantaje ==== 
 +  
 +  - Complexitatea algoritmului poate fi dezavantajoasă dacă sunt puține surse de lumină în scenă 
 +  - Nu se pot folosi metode de netezire a muchiilor folosind accelerație hardware ([[https://​www.khronos.org/​opengl/​wiki/​Multisampling#​Multisampling| multisampling]]). În schimb se pot folosi soluții de sinteză avansată de anti-aliasing,​ precum SSAA, MSAA, FXAA(foarte rapid), TAA, etc. 
 +  - Pentru fiecare informație a suprafeței necesară calculelor de iluminare este necesară adăugarea acestora în G-Buffer pentru fiecare pixel pe ecran. Astfel, se încarcă memoria procesorului grafic. 
 +  - Din cauză că deferred rendering se bazează pe faptul că un singur obiect va fi vizibil per pixel, algoritmul funcționează cât timp obiectele din scenă sunt opace. Obiectele transparente trebuie desenate în alt mod. 
 + 
 +==== Cerințe laborator ==== 
 + 
 +  - Descărcați [[https://​github.com/​UPB-Graphics/​gfx-framework|framework-ul de laborator]] 
 +  - Completați în metoda ''​Init'',​ atribuirea pentru fiecare din cele 40 de surse de lumină din scenă a unei poziții, a unei raze și a unei culori alese aleator. 
 +  - Pentru fiecare sursă de lumină, desenați o sferă la poziția ei, cu o rază egală cu dublul razei de influență a acesteia. Setați variabilele ''​light_position'',​ ''​light_color''​ și ''​light_radius'',​ de tipul uniform, cu informațiile sursei de lumină. 
 +  - În fișierul ''​LightPass.FS.glsl''​ eșantionați texturile din G-buffer și folosiți metoda PhongLight pentru a calcula influența sursei de lumină ce va fi acumulată. 
 +  - Completați în fișierul ''​Composition.FS.glsl'',​ calculul de compoziție între culoarea obiectelor și influența luminilor asupra obiectelor. 
 +  - Realizați o animație de orbitare a surselor de lumină. Orbita pentru fiecare sursă de lumină este în jurul centrului scenei față de axa Oy.
spg/laboratoare/05.txt · Last modified: 2024/04/10 17:33 by robert.caragicu
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