Differences

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

Link to this comparison view

egc:laboratoare:06 [2016/11/20 17:33]
gabriel.ivanica [Cerinte laborator]
egc:laboratoare:06 [2021/11/19 13:08] (current)
victor.asavei [Cerinte laborator]
Line 1: Line 1:
 ===== Laboratorul 06 ===== ===== Laboratorul 06 =====
  
 +**Video Laborator 6**: https://​youtu.be/​f7q2TGCRly0 \\
 +**Autor**: [[maria_anca.balutoiu@upb.ro | Anca Băluțoiu]]
 ==== Banda Grafica ==== ==== Banda Grafica ====
  
-Banda Grafica este un lant de operatii executate de procesoarele GPU. Unele dintre aceste operatii sunt descrise in programe numite ​SHADER-e, care sunt scrise de programator si transmise la GPU pentru a fi executate de procesoarele acestuia. Pentru a le deosebi de alte operatii executate in banda grafica, pe care programatorul nu le poate modifica, ​SHADER-ele ​sunt numite „etape programabile”. Ele dau o mare flexibilitate in crearea de imagini statice sau dinamice cu efecte complexe redate in timp real (apa, nori, foc etc).+Banda Grafica este un lant de operatii executate de procesoarele GPU. Unele dintre aceste operatii sunt descrise in programe numite ​**shadere** (eng. **//​shaders//​**), care sunt scrise de programator si transmise la GPU pentru a fi executate de procesoarele acestuia. Pentru a le deosebi de alte operatii executate in banda grafica, pe care programatorul nu le poate modifica, ​**shaderele** ​sunt numite „etape programabile”. Ele dau o mare flexibilitate in crearea de imagini statice sau dinamice cu efecte complexe redate in timp real (de ex. generarea de apa, nori, foc etc prin functii matematice).
  
 Folosind OpenGL sunt transmise la **GPU**: coordonatele varfurilor, matricile de transformare a varfurilor (M: modelare, V: vizualizare,​ P: proiectie, MV: modelare-vizualizare,​ MVP: modelare-vizualizare-proiectie),​ topologia primitivelor,​ texturi si ale date. Folosind OpenGL sunt transmise la **GPU**: coordonatele varfurilor, matricile de transformare a varfurilor (M: modelare, V: vizualizare,​ P: proiectie, MV: modelare-vizualizare,​ MVP: modelare-vizualizare-proiectie),​ topologia primitivelor,​ texturi si ale date.
Line 9: Line 11:
 {{ :​egc:​laboratoare:​banda_grafica.png?​nolink&​500 |}} {{ :​egc:​laboratoare:​banda_grafica.png?​nolink&​500 |}}
  
-1. In **etapa programabila VERTEX SHADER** se transforma coordonatele unui varf, folosind matricea MVP, (din coordonate obiectin coordonate de decupare (clip coordinates). De asemenea, pot fi efectuate si calcule de iluminare la nivel de varf. Programul VERTEX SHADER este executat in paralel pentru un numar foarte mare de varfuri.+1. In **etapa programabila VERTEX SHADER** se transforma coordonatele unui varf, folosind matricea MVP, din coordonate obiect in coordonate de decupare (eng. //clip coordinates//). De asemenea, pot fi efectuate si calcule de iluminare la nivel de varf. Programul VERTEX SHADER este executat in paralel pentru un numar foarte mare de varfuri.
  
-2. Urmeaza o **etapa fixa**, in care sunt efectuate urmatoarele operatii:  +2. Urmeaza o **etapa fixa**, in care sunt efectuate urmatoarele operatii: 
-* asamblarea primitivelor folosind varfurile transformate in vertex shader si topologia primitivelor;​ +   ​* asamblarea primitivelor folosind varfurile transformate in vertex shader si topologia primitivelor;​ 
-* eliminarea fetelor nevizibile;​ +   ​* eliminarea fetelor nevizibile;​ 
-* decuparea primitivelor la frontiera volumului ​vizual ​canonic; +   ​* decuparea primitivelor la frontiera volumului canonic ​de vizualizare ([[https://​gamedev.stackexchange.com/​q/​6279|ce inseamna?​]])
-* impartirea perspectiva,​ prin care se calculeaza coordonatele dispozitiv normalizate ale varfurilor: ​ xd = xc/w; yd = yc/w;zd = zc/w, unde [xc,​yc,​zc,​w] reprezinta coordonatele unui varf in sistemul coordonatelor de decupare; +   ​* impartirea perspectiva,​ prin care se calculeaza coordonatele dispozitiv normalizate ale varfurilor: ​ xd = xc/w; yd = yc/w;zd = zc/w, unde [xc,​yc,​zc,​w] reprezinta coordonatele unui varf in sistemul coordonatelor de decupare; 
-* transformarea fereastra–poarta:​ din fereastra (-1, -1) – (1, 1) in viewport-ul definit de programator.+   ​* transformarea fereastra–poarta:​ din fereastra (-1, -1) – (1, 1) in viewport-ul definit de programator.
  
 3. Urmatoarea etapa este **Rasterizarea**. Aceasta include: 3. Urmatoarea etapa este **Rasterizarea**. Aceasta include:
-  ​* calculul adreselor pixelilor in care se afiseaza fragmentele primitivelor (bucatele de primitive de dimensiune egala cu a unui pixel); +   * calculul adreselor pixelilor in care se afiseaza fragmentele primitivelor (bucatele de primitive de dimensiune egala cu a unui pixel); 
-  * calculul culorii fiecarui fragment, pentru care este apelat programul **FRAGMENT SHADER** +   ​* calculul culorii fiecarui fragment, pentru care este apelat programul **FRAGMENT SHADER** 
-  * in etapa programabila **FRAGMENT SHADER** se calculeaza culoarea unui fragment pe baza geometriei si a texturilor; programul **FRAGMENT SHADER** este executat in paralel pentru un numar mare de fragmente. +   ​* in etapa programabila **FRAGMENT SHADER** se calculeaza culoarea unui fragment pe baza geometriei si a texturilor; programul **FRAGMENT SHADER** este executat in paralel pentru un numar mare de fragmente. 
-  * testul de vizibilitate la nivel de fragment (algoritmul z-buffer);​ +   ​* testul de vizibilitate la nivel de fragment (algoritmul z-buffer);​ 
-  * operatii raster, de exemplu pentru combinarea culorii fragmentului cu aceea existenta pentru pixelul in care se afiseaza fragmentul.+   ​* operatii raster, de exemplu pentru combinarea culorii fragmentului cu aceea existenta pentru pixelul in care se afiseaza fragmentul.
  
  
-Rezultatul etapei de rasterizare este o **imagine** memorata ​in //frame buffer//.+Rezultatul etapei de rasterizare este o **imagine** memorata ​intr-un tablou de pixeli ce va fi afisat pe ecran, numit //^^frame buffer^^//.
  
-<​note>​Incepand cu a 5-a generatie ​GPU si OpenGL 3.x, intre etapele 2 si 3 exista inca o etapa programabila,​ numita //Geometry shader//​.</​note>​+<​note>​Incepand cu [[https://​en.wikipedia.org/​wiki/​List_of_Intel_graphics_processing_units#​Fifth_generation|cincea ​generatie]] de procesoare video integrate ​si OpenGL 3.x, intre etapele 2 si 3 exista inca o etapa programabila,​ numita //**Geometry shader**//​.</​note>​
  
 ==== Shader OpenGL ==== ==== Shader OpenGL ====
Line 54: Line 56:
 </​code>​ </​code>​
  
-Un __**FRAGMENT SHADER**__ e un program ce este executat pentru __**FIECARE**__ fragment generat de rasterizator. Fragment shader are o functie numita main. Un exemplu de fragment shader:+Un __**FRAGMENT SHADER**__ e un program ce este executat pentru __**FIECARE**__ fragment generat ​in urma operatiei ​de rasterizare ([[https://​graphicdesign.stackexchange.com/​q/​260|ce inseamna?​]]). Fragment shader are in mod obligatoriu ​o functie numita main. Un exemplu de fragment shader:
  
 <code glsl> <code glsl>
Line 81: Line 83:
 Prima comanda seteaza pipe-ul cu numarul 2 ca fiind utilizat. ​ Prima comanda seteaza pipe-ul cu numarul 2 ca fiind utilizat. ​
 A doua comanda descrie structura datelor in cadrul VBO-ului astfel: A doua comanda descrie structura datelor in cadrul VBO-ului astfel:
-  * pe pipe-ul **2** se primesc ​3 float-uri (argument 3) pe care nu le normalizam (argument 4) +  * pe pipe-ul **2** se trimit la shader ​3 float-uri (argument 3) pe care nu le normalizam (argument 4) 
-  * argumentul 5 numit si **stride**, identifica pasul de citire (in bytes) in cadrul VBO-ului pentru a obtine urmatorul atribut +  * argumentul 5 numit si **stride**, identifica pasul de citire (in bytes) in cadrul VBO-ului pentru a obtine urmatorul atribut; cu alte cuvinte, din cati in cati octeti sarim cand vrem sa gasim un nou grup de cate 3 float-uri care reprezinta acelasi lucru 
-  * argumentul 6 identifica offsetul inital din cadrul buffer-ul legat la GL_ARRAY_BUFFER (VBO)+  * argumentul 6 identifica offsetul inital din cadrul buffer-ul legat la GL_ARRAY_BUFFER (VBO); cu alte cuvinte, de unde plecam prima oara.
  
 In __Vertex Shader__ vom primi atributul respectiv pe pipe-ul cu indexul specificat la legare, astfel: In __Vertex Shader__ vom primi atributul respectiv pe pipe-ul cu indexul specificat la legare, astfel:
Line 99: Line 101:
 </​note>​ </​note>​
  
 +<note tip> Un articol despre istoria complicata a OpenGL si competitia cu Direct3D/​DirectX poate fi citit [[https://​softwareengineering.stackexchange.com/​q/​60544|aici]].
 +</​note>​
  
 ==== Cum trimitem date generale la un shader? ==== ==== Cum trimitem date generale la un shader? ====
Line 105: Line 109:
  
 <code cpp> <code cpp>
-int location = glGetUniformLocation(int shader_program,​ "​uniform_variable_name_in_shader"​)**+int location = glGetUniformLocation(int shader_program,​ "​uniform_variable_name_in_shader"​);
 </​code>​ </​code>​
  
   * **shader_program** reprezinta ID-ul programului shader compilat pe placa video   * **shader_program** reprezinta ID-ul programului shader compilat pe placa video
-  * in cadrul framework-ului de laborator ID-ul se poate obtine apeland functia ''​shader->​GetProgramID()''​ sau direct accesand ​vriabila ​membru ''​shader->​program''​+  * in cadrul framework-ului de laborator ID-ul se poate obtine apeland functia ''​shader->​GetProgramID()''​ sau direct accesand ​variabila ​membru ''​shader->​program''​
  
  
Line 192: Line 196:
 </​note>​ </​note>​
  
-  - Descarcati [[https://​github.com/​UPB-Graphics/​Framework-EGC/​archive/​master.zip|framework-ul de laborator]]+  - Descarcati [[https://​github.com/​UPB-Graphics/​gfx-framework/​archive/​master.zip|framework-ul de laborator]]
   - Completati functia ''​RenderSimpleMesh''​ astfel inca sa trimiteti corect valorile uniform catre Shader   - Completati functia ''​RenderSimpleMesh''​ astfel inca sa trimiteti corect valorile uniform catre Shader
     * Se interogeaza locatia uniformelor "​Model",​ "​View"​ si "​Projection"​     * Se interogeaza locatia uniformelor "​Model",​ "​View"​ si "​Projection"​
     * Folosind ''​glUniformMatrix4fv''​ sa se trimita matricile corespunzatoare catre shader     * Folosind ''​glUniformMatrix4fv''​ sa se trimita matricile corespunzatoare catre shader
-    * Daca ati completat corect functia ar trebui sa vedeti un cub pe centrul ecranului rottit 45 grade in jurul lui Y si colorat variat+    * Daca ati completat corect functia, si ati completat gl_Position in vertex shader, ​ar trebui sa vedeti un cub pe centrul ecranului rottit 45 grade in jurul lui Y si colorat variat
   - Completati Vertex Shaderul   - Completati Vertex Shaderul
-    ​Se declara atributele de intrare pentru ''​Vertex Shader''​ folosind layout location <code glsl>+    ​Se declara atributele de intrare pentru ''​Vertex Shader''​ folosind layout location <code glsl>
  layout(location = 0) in vec3 v_position;  layout(location = 0) in vec3 v_position;
- // same for the rest of the attributes+ // same for the rest of the attributes ​( check Lab6.cpp CreateMesh() ); 
 </​code>​ </​code>​
-    ​Se declara atributele de iesire catre ''​Fragment Shader''​ <code glsl>+    ​Se declara atributele de iesire catre ''​Fragment Shader''​ <code glsl>
  out vec3 frag_color;  out vec3 frag_color;
  // same for other attributes  // same for other attributes
 </​code>​ </​code>​
-    ​Se salveza valorile de iesire in ''​main()''​ <code glsl>+    ​Se salveza valorile de iesire in ''​main()''​ <code glsl>
  frag_color = vertex_color;​  frag_color = vertex_color;​
  // same for other attributes  // same for other attributes
 </​code>​ </​code>​
-    ​Se calculeaza pozitia in clip space a vertexului primit folosind matricile Model, View, Projection <code glsl>+    ​Se calculeaza pozitia in clip space a vertexului primit folosind matricile Model, View, Projection <code glsl>
  gl_Position = Projection * View * Model * vec4(v_position,​ 1.0);  gl_Position = Projection * View * Model * vec4(v_position,​ 1.0);
 </​code>​ </​code>​
Line 221: Line 226:
  out_color = vec4(frag_color,​ 1);  out_color = vec4(frag_color,​ 1);
 </​code>​ </​code>​
-  - Sa se primeasca toate atributele trimise de catre vertex shader conform locatiilor utilizate in functia ''​Laborator6::​CreateMesh''​ 
   - Sa se utilizeze normala vertexilor pe post de culoare de output in cadrul Fragment Shader-ului   - Sa se utilizeze normala vertexilor pe post de culoare de output in cadrul Fragment Shader-ului
     * Inspectati de asemenea structura ''​VertexFormat''​ pentru a intelege ceea ce se trimite pe fiecare pipe     * Inspectati de asemenea structura ''​VertexFormat''​ pentru a intelege ceea ce se trimite pe fiecare pipe
   - Sa se interschimbe **pipe-ul 1** cu **pipe-ul 3**. Trimiteti normala pe **pipe-ul 3** si culoarea vertexului pe **pipe-ul 1**   - Sa se interschimbe **pipe-ul 1** cu **pipe-ul 3**. Trimiteti normala pe **pipe-ul 3** si culoarea vertexului pe **pipe-ul 1**
     * Se inspecteaza rezultatul obtinut     * Se inspecteaza rezultatul obtinut
 +  - Bonus: sa se trimita timpul aplicatiei (Engine::​GetElapsedTime()),​ si sa se varieze pozitia si culoarea (unul sau mai multe canale de culoare) dupa o functie de timp (trigonometrica etc.)
  
 <​hidden>​ <​hidden>​
 +  - Sa se primeasca toate atributele trimise de catre vertex shader conform locatiilor utilizate in functia ''​Laborator6::​CreateMesh''​
 **[Bonusuri posibile]** **[Bonusuri posibile]**
   * displacement in vertex shader   * displacement in vertex shader
egc/laboratoare/06.1479656037.txt.gz · Last modified: 2016/11/20 17:33 by gabriel.ivanica
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