Differences

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

Link to this comparison view

ppbg:laboratoare:08 [2023/12/06 23:06]
andrei.lambru
ppbg:laboratoare:08 [2024/11/27 22:13] (current)
andrei.lambru
Line 4: Line 4:
 **Reamintire!!!** Puteți prezenta rezolvările cerințelor de până la 2 laboratoare,​ în fiecare săptămână. De exemplu, puteți prezenta laboratorul curent și pe cel din săptămâna anterioară,​ în totalitate sau parțial, inclusiv punctajul pentru cerința bonus :) . **Reamintire!!!** Puteți prezenta rezolvările cerințelor de până la 2 laboratoare,​ în fiecare săptămână. De exemplu, puteți prezenta laboratorul curent și pe cel din săptămâna anterioară,​ în totalitate sau parțial, inclusiv punctajul pentru cerința bonus :) .
 </​note>​ </​note>​
 +
 +===== Obiecte de tip textură =====
 +
 +Un obiect de tip textură reprezintă o secvență continuă de informație în interiorul memoriei RAM a procesorului grafic. În particular, în cadrul acestui laborator, ne referim la obiecte de tip textură ce păstrează informația din interiorul unei grile de două dimensiuni.
 +
 +Într-o grilă de două dimensiuni, putem stoca informația unei imagini :) în care, în fiecare celulă, păstrăm informația unui pixel.
  
 <note tip> <note tip>
-Pentru rezolvarea cerințelor din cadrul acestui labroator+General, în API-ul grafic OpenGL, un obiect de tip textură poate fi de mai multe tipuri
-  ​- [[https://​github.com/​UPB-Graphics/​gfx-framework-ppbg | Descărcați]] framwork-ul ​de laborator și copiați, din arhiva descărcată, directorul **Lab8**, în interiorul directorului //​gfx-framework-ppbg\src\lab//​ din versiunea voastră de proiect+  ​* O grilă cu o singură dimensiune. 
-  ​- Adăugați în fișierul ''​lab_list.h'',​ linia ''#​include "​lab/​lab8/​lab8.h"''​+  * O grilă de două dimensiuni. 
-  ​- Folosiți din nou utilitarul CMake pentru a regenera proiectul. Pentru a vă reaminti procesul de realizare a setup-ului, puteți ​să reconsultați [[:ppbg:setup-framework | pagina]] dedicată acestui lucru.+  * O grilă de trei dimensiuni. 
 +  ​O textură cubicăce păstrează informația a 6 grile de două dimensiuni
 +  ​* Un set de grile cu o singură dimensiune. 
 +  * Un set de grile de două dimensiuni
 +  ​* ... 
 +Pentru a vizualiza toate tipurile posibile, puteți ​consulta documentația oficială: https://​www.khronos.org/​opengl/​wiki/​Texture#​Theory.
 </​note>​ </​note>​
  
-===== Programe de tip shader pentru prelucrarea geometriei ​=====+===== Proiectarea texturilor ​=====
  
-In acest laboratorse introduce un alt tip de program de tip shader ​ce are rolul de a prelucra geometrie, precum triunghiuriAcest tip de program ​are scopul de oferi control dezvoltatorilor asupra geometriei desenateIn banda grafica, el apare dupa pasul de executie a programelor ​de tip vertex shader si dupa asamblarea informatiilor varfurilorobtinute ​de la aceste programesub forma de triunghiuripe baza indicilor specificati in [[ https://ocw.cs.pub.ro/​courses/​ppbg/​laboratoare/​04#​index_buffer_object_ibo | IBO]]. Acest proces ​poate fi vizualizat in imaginea de mai jos.+Conținutul informației unei imagini se poate proiecta pe suprafața unui model 3Drespectiv pe suprafața triunghiurilor din care este compusă rețeaua ​de triunghiuri ​ce descrie modelul 3D, prin utilizarea unei informații suplimentare,​ în fiecare vârf, denumită **coordonată ​de textură**O astfel ​de coordonată ​are două dimensiuni și fiecare componentă ​ei, respectiv x și y, se află în intervalul [0,1]Aceasta este coordonata în spațiul finit al grilei 2D stocate în obiectul ​de tip texturăspațiu delimitat în colțul din stânga-jos ​de coordonata (00) și în colțul din dreapta-sus ​de coordonata (11)Un astfel de spațiu ​poate fi utilizat pentru a eșantiona valorile din grilă.
  
-{{ :ppbg:​laboratoare:​geometry-shader.png?600 |}}+Pentru a exemplifica,​ în partea stângă a imaginii de jos se poate observa un triunghi pentru care s-au asociat în vârfuri coordonate de textură(0.7, 0.75), (0.1, 0.3) și (0.95, 0.2). Presupunem că prin procesul de rasterizare,​ s-a obținut un pixel ce se află în interiorul acestui triunghi și care a obținut prin interpolare de la vârfuri coordonata de textură (0.7, 0.55). Prin transformarea acestei coordonate în spațiul grilei 2D, obținem valoarea (716.8, 563.2).
  
-Pentru fiecare triunghi rezultat in urma procesului de asamblare pe baza indicilor din IBO, se apeleaza o singura instanta de program de tip geometry shader.+{{ :​ppbg:​laboratoare:​texture-mapping.png?600 |}}
  
-====== Sintaxa limbajului GLSL ====== +Avem mai multe posibilități pentru a eșantiona o valoare din informația celulelor din grila 2D.
-Un exemplu de vertex shader: +
-<code glsl> +
-#version 330 +
-  +
-layout(location = 0) in vec3 v_position;​ +
-layout(location = 1) in vec2 v_texcoord;+
  
-uniform mat4 Model; +==== Eșantionare directă ====
-uniform mat4 View; +
-uniform mat4 Projection;+
  
-// coordonatele ​de textură ale vârfului +Se eșantioneaza direct valoarea celulei ​de la coordonata în spațiul grilei 2D, cu valoarea fiecărei componente a coordonatei rotunjită în jos. Astfel, ​pentru ​exemplul ​de sus, unde coordonata de texturare este (716.8, 563.2), se eșantionează valoarea celulei (716, 563).
-// atributele de iesire ale unui program de tip vertex shader +
-// sunt atribute de intrare ​pentru ​un program ​de tip geometry shader +
-out vec2 vert_texcoord;​+
  
-void main() +==== Eșantionare liniară ==== 
-{ + 
-    ​gl_Position ​Projection * View * Model * vec4(v_position1.0); +O altă variantă utilizează o eșantionare a informației prin interpolare liniară de la toate celulele din jurul coordonatei,​ respectiv:​ 
-     + 
-    ​vert_texcoord ​v_texcoord+<code cpp> 
-}+glm::vec3 c1 = glm::vec3(716, 563); 
 +glm::vec3 c2 = glm::​vec3(716,​ 564); 
 +glm::vec3 c3 glm::vec3(717563); 
 +glm::vec3 c4 = glm::​vec3(717,​ 564); 
 + 
 +glm::vec3 c12 glm::​mix(c1,​ c2, 0.8)// din partea fractionara a componentei x, 716.8 
 +glm::vec3 c34 = glm::​mix(c3,​ c4, 0.8); // din partea fractionara a componentei x, 716.8 
 + 
 +glm::vec3 c1234 = glm::​mix(c12,​ c34, 0.2) // din partea fractionara a componentei y, 563.2
 </​code>​ </​code>​
  
-Un exemplu de geometry shader: +<note tip
-<code glsl+''​glm::​mix()''​ reprezintă interpolare liniară:
-#version 330+
  
-// geometria primita la intrare este formata dintr-un triunghi 
-layout(triangles) in; 
  
-// geometria transmisa la iesire 
-layout(triangle_strip,​ max_vertices = 3) out; 
  
-// atribut de intrare - coordonatele de textură ale vârfurilor unui triunghi +$$ 
-layout(location ​0in vec2 vert_texcoord[3];​+mix(a, b, t) (1-t\cdot a + t \cdot b 
 +$$
  
-// atribut de iesire - coordonatele textură asociate fiecărui vârf emis 
-layout(location = 0) out vec2 geom_texcoord;​ 
  
-void main() 
-{ 
- gl_Position = gl_in[0].gl_Position;​ 
- geom_texcoord = vert_texcoord[0];​ 
- EmitVertex();​ 
  
- gl_Position = gl_in[1].gl_Position;​ +</​note>​
- geom_texcoord = vert_texcoord[1];​ +
- EmitVertex();​+
  
- gl_Position = gl_in[2].gl_Position;​ +<note tip> 
- geom_texcoord = vert_texcoord[2];​ +Acest proces este regăsit în limba engleză sub numele de **bilinear interpolation**. 
- EmitVertex();​+</​note>​
  
- EndPrimitive();​ +==== Piramida „mipmap” ====
-        //directiva aceasta încheie primitiva  +
-+
-</​code>​+
  
-==== Atribute ​de intrare ​și de iesire ====+Conceptul ​de piramidă „mipma” a fost propus de Lance Williams în anul 1983 și constă în stocarea unei „piramide” de versiuni de diferite rezoluții ale unei imagini. Un astfel de exemplu se poate observa în imaginea de mai jos, în care în aceeași grilă, în partea stângă este stocată imaginea la rezoluția inițială, iar în partea dreaptă sunt stocate versiunile imaginii inițiale la rezoluție de 2, 4, 8, până la 128 de ori mai mică.
  
-  * Trebuie specificat tipul geometriei de la intrare<code glsl> +{{ :ppbg:laboratoare:​mipmap.jpg?300 |}}
-layout(triangles) in; +
-</​code>​ Trebuie să fie unul dintre''​points'',​ ''​lines'',​ ''​lines_adjacency'',​ ''​triangles'',​ ''​triangles_adjacency''​. Aceste tipuri de date sunt descrise intr-o sectiune urmatoare.+
  
-  * Trebuie specificat tipul geometriei de la ieșire: ​<code glsl+<note tip
-layout(triangle_stripmax_vertices = 5) out; +Termenul de „mipmap” provine de la primele litere ale cuvintelor din fraza în limba latină //multum in parvo//mip, ceea ce în limba română se traduce prin //mult în puțin// și de la termenul de „map” din limba engleză, ceea ce în limba română se traduce prin hartă. 
-</code> Trebuie să fie unul dintre: ''​points''​''​line_strip'',​ ''​triangle_strip''​. Aceste tipuri de date sunt descrise intr-o sectiune urmatoare.+</​note>​
  
-  * Se primesc coordonatele de textură de la toată primitiva (triunghiul)Astfel ​că intrarea ​este un vector ​de valori ​''​vec2''​. <code glsl+Această piramidă este utilă în momentul în care este dorită o eșantionare într-o vecinatate mai mare de 2x2. Situația aceasta apare în momentul în care prin procesul de interpolare,​ doi pixeli vecini obținuti prin rasterizare au atribuite coordonate de texturare ce in grila 2D se află la distanță mai mare de o celulă. De exemplu, dacă doi pixeli vecini se află la distanță de 50 de celule în grila 2D, putem considera ​că dimensiunea pixelului, în spațiul grilei 2D este de 50 de celule. Astfel, putem utiliza versiunile imaginii ce au rezoluția cea mai apropiată de dimensiunea pixelului. Pentru imaginea de mai sus, aceste versiuni au rezoluție de 64x64 și 32x32. Pentru eșantionare,​ avem două opțiuni. 
-layout(location = 0) in vec2 vert_texcoord[3];​ + 
-</code>  +=== Eșantionare directă === 
-  * Nu este necesar să se dea dimensiunea vectorului. Astfelcodul de mai sus se poate scrie: <​code ​glsl+ 
-layout(location = 0in vec2 vert_texcoord[];+Se eșantionează direct sau liniar DOAR versiunea imaginii ce are rezoluția cea mai apropiată. Pentru exemplul de mai sus, se alege versiunea imaginii de rezoluție 64x64. 
 + 
 +=== Eșantionare liniară === 
 + 
 +Se eșantionează direct sau liniar cele două versiuni ale imaginii ce au rezoluția cea mai apropiată și se interpolează liniar între cele două valori ​obținute din eșantionarea celor două versiuni. 
 + 
 +<note tip
 +Procesul de eșantionare,​ cu toate opțiunile menționate mai sus, este implementat hardware în interiorul procesorului grafic. 
 +</note
 + 
 +===== Gestionarea obiectelor de tip textură în API-ul grafic OpenGL ===== 
 + 
 +==== Crearea unui obiect de tip textură ==== 
 + 
 +Pentru gestionarea unui obiect de tip textură în API-ul grafic OpenGLtrebuie creat un astfel ​de obiect: 
 + 
 +<​code ​cpp
 +unsigned int texture_id;​ 
 + 
 +glGenTextures(1, &​texture_id);
 </​code>​ </​code>​
  
-  * De asemenea, există și un atribut implicit într-un program ​de tip geometry shadercu numele ''​gl_in'',​ din care ne interesează ''​gl_Position''​: <​code ​glsl+Pentru a modifica informațiile stocate de obiectul ​de tip textură sau pentru a utiliza obiectulel trebuie legat: 
-in gl_PerVertex + 
-+<​code ​cpp
-  vec4 gl_Position;​ +glBindTexture(GL_TEXTURE_2D,​ texture_id);
-  ... +
-} gl_in[];+
 </​code>​ </​code>​
  
-  * Atributele de ieșire ale unui program ​de tip geometry shader sunt descrise în secțiunea următoare: <​code ​glsl+Pentru a asocia informație obiectului ​de tip textură, se utilizează: 
-layout(location = 0) out vec2 geom_texcoord;+ 
 +<​code ​cpp
 +glTexImage2D(GL_TEXTURE_2D,​ 0, GL_RGB, width, height, ​0, GL_RGB, GL_UNSIGNED_BYTE,​ data);
 </​code>​ </​code>​
  
-==== Emiterea ​de primitive ====+<note tip> 
 +Directiva ​de mai sus este complexă și suportă foarte mulți parametri. Pentru mai multe detalii, puteți consulta documentația oficială: https://​registry.khronos.org/​OpenGL-Refpages/​gl4/​html/​glTexImage2D.xhtml. 
 +</​note>​
  
-Pentru fiecare vârf emis dintr-un program ​de tip geometry shaderse poate asocia ​informație despre coordonata de textură, vectorul normal, culoarea și orice alt tip de informație asociată vârfului (specificate înainte de fiecare apel ''​EmitVertex()''​)+<note important>​ 
-Acestea trebuie declarate ca variabile ​de ieșire. +Directiva ''​glTexImage2D()''​ asociază primele celule din memorie cu linia din partea ​de **jos** a grilei 2D. Din acest motivputem considera că API-ul grafic OpenGL încarcă ​informația în memorie în formă rasturnată pentru componenta y. 
-După cum se poate observa, valoarea lui ''​geom_texcoord''​ este actualizată înainte de fiecare apel ''​EmitVertex()''​:<​code ​glsl+</​note>​ 
-gl_Position = gl_in[0].gl_Position+ 
-geom_texcoord = vert_texcoord[0];​ +Suplimentarse pot specifica parametri pentru diferite procese în care este implicat obiectul de tip textură. 
-EmitVertex();+ 
 +Pentru procesul ​de eșantionare, ​se pot specifica parametrii: 
 + 
 +<​code ​cpp
 +glTexParameteri(GL_TEXTURE_2D,​ GL_TEXTURE_MIN_FILTER,​ GL_NEAREST)
 +glTexParameteri(GL_TEXTURE_2D,​ GL_TEXTURE_MAG_FILTER,​ GL_LINEAR);
 </​code>​ </​code>​
  
-Într-un geometry shader, se pot emite mai multe primitive (comanda ''​EmitVertex()''​ se poate da o dată sau de mai multe ori).+<note tip> 
 +Procesul ​de eșantionare este cunoscut sub numele de **filtrare**.
  
-==== Tipuri ​de primitive ====+Pentru parametrul ​de filtrare, în situația în care doi pixeli vecini obținuti prin rasterizare au coordonate de textură la distanță mai mare de o celulă din grila 2D, prin parametrul ''​GL_TEXTURE_MIN_FILTER''​ se poate specifica:​ 
 +  * ''​GL_NEAREST''​ - eșantionare directă doar din imaginea inițială. 
 +  * ''​GL_LINEAR''​ - eșantionare liniară doar din imaginea inițială. 
 +  * ''​GL_NEAREST_MIPMAP_NEAREST'':​ eșantionare directă din versiunea imaginii inițiale ce are rezoluția cea mai apropiată de dimensiunea pixelului în spațiul grilei 2D. 
 +  * ''​GL_LINEAR_MIPMAP_NEAREST'':​ eșantionare liniară din versiunea imaginii inițiale ce are rezoluția cea mai apropiata de dimensiunea pixelului în spațiul grilei 2D. 
 +  * ''​GL_NEAREST_MIPMAP_LINEAR'':​ interpolare liniară între valorile obținute prin eșantionare directă a versiunilor imaginii inițiale ce au rezoluțiile cele mai apropiate de dimensiunea pixelului în spațiul grilei 2D. 
 +  * ''​GL_LINEAR_MIPMAP_LINEAR'':​ interpolare liniară între valorile obținute prin eșantionare liniară a versiunilor imaginii inițiale ce au rezoluțiile cele mai apropiate de dimensiunea pixelului în spațiul grilei 2D.
  
-La iesirea unui program ​de tip geometry shaderse permit doar 3 tipuri ​de date, cum fost mentionat ​mai sus: ''​points''​, ''​line_strip'' ​si ''​triangle_strip''​. Descrierea topologiei pentru fiecare tip de date este dupa cum urmeaza+Pentru parametrul ​de filtrareîn situația în care doi pixeli vecini obținuti prin rasterizare au coordonate ​de textură la distanța mai mică de o celulă din grila 2Dprin parametrul ​''​GL_TEXTURE_MAG_FILTER'' ​se poate specifica
-  * ''​points''​: se deseneaza un singur pixel, la pozitia ​din poarta de afisare in care se regaseste fiecare varf emis de un program de tip geometry shader. Un astfel de exemplu este reprezentat vizual in imaginea ​de mai jos+  * ''​GL_NEAREST'' ​- eșantionare directă doar din imaginea ​inițială
-  * ''​line_strip''​: se deseneaza linii intre fiecare pereche consecutiva de varfuri emise de un program de tip geometry shader. Dupa cum se poate urmari in panoul ​din mijloc al imaginii de mai jos, pentru o lista de 6 varfuri emise in ordinea { v0, v1, v2, v3, v4, v5 }, se creeaza o linie intre varfurile { v0, v1 }, { v1, v2 }, { v2, v3 }, { v3, v4 } si { v4, v5 }. +  * ''​GL_LINEAR'' ​- eșantionare liniară doar din imaginea inițială.
-  * ''​triangle_strip'':​ se deseneaza triunghiuri pentru toate tripletele consecutive de varfuri emise de un program de tip geometry shader. Dupa cum se poate urmari in panoul din dreapta al imaginii de mai jos, pentru o lista de 7 varfuri emise in ordinea { v0, v1, v2, v3, v4, v5, v6 }, se creeaza un triunghi cu varfurile { v0, v1, v2 }, { v1, v2, v3 }, { v2, v3, v4 }, { v3, v4, v5 } si { v4, v5, v6 }.+
  
-{{ :ppbg:laboratoare:​triangles.png?600 |}}+Pentru mai multe detalii în legatură cu parametrii ce pot fi specificați,​ puteți consulta documentația oficialăhttps://​registry.khronos.org/​OpenGL-Refpages/​gl4/​html/​glTexParameter.xhtml. 
 +</​note>​
  
-La intrarea unui program de tip geometry shader se permit 5 tipuri de date, cum fost mentionat mai sus: ''​points'',​ ''​lines'',​ ''​lines_adjacency'',​ ''​triangles'',​ ''​triangles_adjacency''​. Pentru toate tipurile de date se primeste de fapt **o singura instanta** din acel tip la executia unei instante de program de tip geometry shader. Diferenta principala intre aceste tipuri este data de numarul de atribute de intrare primite in ''​gl_in''​ si in cele proprii programelor de tip shader. Mai exact: +Pentru ​genera piramida „mipmap” ​se utilizează:
-  * ''​points'':​ se primeste exact //un singur// element in atributele de intrare. +
-  * ''​lines'':​ se primesc //doua// elemente in atributele de intrare. +
-  * ''​lines_ajacency'':​ se primesc //4// elemente in atributele de intrare. +
-  * ''​triangles'':​ se primesc //3// elemente in atributele de intrare. +
-  * ''​triangles_adjacency'':​ se primesc //6// elemente in atributele de intrare.+
  
-===== Prelucrari la nivel de triunghi =====+<code cpp> 
 +glGenerateMipmap(GL_TEXTURE_2D);​ 
 +</​code>​
  
-Printre prelucrarile frecvente asupra unui triunghi, se numara calcularea unui centru si a vectorului perpendicular pe planul triunghiului.+==== Unitatea de texturare ====
  
-Se poate calcula centroidul ​unui triunghi cu urmatoarea abordare: +Procesul de eșantionare este realizat de o entitate autonomă implementată hardware sub forma unui procesor în interiorul procesorului grafic sau software în driver-ul companion procesoruluiAceastă entitate autonomă este numită **unitate de texturare** și numărul lor este în general limitat la 32.
-<code glsl> +
-vec3 p1 = gl_in[0].gl_Position.xyz; +
-vec3 p2 = gl_in[1].gl_Position.xyz;​ +
-vec3 p3 = gl_in[2].gl_Position.xyz;​+
  
-vec3 center = (p1 + p2 + p3/ 3;+Pentru a utiliza procesul de eșantionare,​ trebuie să asociem obiectul de tip textură pe care dorim sa îl eșantionăm cu o unitate de texturare, numerotat cu identificatori de la 0 la 31 și să transmitem la un program de tip shader numărul unității de texturare:​ 
 + 
 +<code cpp> 
 +glActiveTexture(GL_TEXTURE0);​ 
 + 
 +glBindTexture(GL_TEXTURE_2D,​ texture_id);​ 
 + 
 +glUniform1i(glGetUniformLocation(shader->​program,​ "​texture_unit"​),​ 0);
 </​code>​ </​code>​
  
-Se poate calcula vectorul perpendicular pe planul triunghiului cu abordarea:+Pentru a utiliza unitatea de texturare, putem folosi într-un program de tip shader ''​texture()''​: 
 <code glsl> <code glsl>
-vec3 p1 = gl_in[0].gl_Position.xyz;​ +#version 330 
-vec3 p2 = gl_in[1].gl_Position.xyz+  
-vec3 p3 = gl_in[2].gl_Position.xyz;+uniform sampler2D texture_unit
 +  
 +in vec2 texture_coord;
  
-vec3 v12 = normalize(p2 - p1); +layout(location ​0out vec4 out_color;
-vec3 v13 normalize(p3 - p1);+
  
-// produs vectorial +void main() 
-vec3 normal ​cross(v12v13);+
 + vec4 color texture(texture_unittexture_coord); 
 + out_color = color; 
 +}
 </​code>​ </​code>​
  
-===== Cerinte laborator ======+===== Stocarea unor informații generice ​=====
  
-  - 0.05p - Completati fisierele ''​LabShader.GS.glsl''​ si ''​Texture.FS.glsl''​ pentru a desena geometria arcasei pe baza texturii. Dupa acest pas, rezultatul vizual ar trebui sa fie urmatorul: {{ :​ppbg:​laboratoare:​geometry-shader1.png?​600 |}} +În interiorul memoriei stocate ​de un obiect ​de tip textură, se pot păstra informații generice.
-  - 0.05p - Modificati programul ​de tip geometru shader din fisierul ''​LabShader.GS.glsl''​ pentru a desena obiectul pentru care se utilizeaza de cel putin 5 ori, la pozitii diferite in scena. Poate fi aliniat pe aceeasi linie. +
-  - 0.1p - Completati fisierele ''​Triangle.GS.glsl''​ si ''​Color.FS.glsl''​ pentru a obtine urmatorul rezultat vizual: {{ :​ppbg:​laboratoare:​geometry-shader2.png?​600 |}} +
-    * Geometria primita la intrare de programul de tip geometry shader contine ​un singur triunghi. Pentru a obtine rezultatul vizual din imagine, la iesire trebuie transmise mai multe triunghiuri :) . +
-  - 0.05p - Creati un alt program ​de tip geometry shader cu care sa realizati o animatie de "​explozie"​ a geometriei similara cu cea din imaginea urmatoare: {{ :​ppbg:​laboratoare:​geometry-shader.gif?​600 |}} +
-    * Aveti in vedere ca animatia de "​explozie"​ se reseteaza dupa un interval de timp. Hint: utilizati timpul aplicatiei si informatia vectorilor normali. +
-  - 0.05p - Creati un alt program de tip geometry shader cu care sa desenati marcaje liniare ce specifica directia normalei in fiecare varf al retelei de triunghiuri ce formeaza geometria: {{ :​ppbg:​laboratoare:​geometry-shader3.png?​600 |}} +
-    * Desenati de doua ori geometria. Odata triunghiurile peste care se aplica textura. O a doua oara in care se utilizeaza programul de tip geometry shader doar pentru desenarea liniilor ce reprezinta vectorii normali. +
-    * Trebuie desenata o linie pentru fiecare varfcu care se specifica directia vectorului normal din informatia varfului +
-    * Rezultatul vizual ar trebui sa fie similar cu cel din imaginea de mai jos:+
  
-Bonus: Creati ​un alt program de tip geometry ​shader ​cu care sa realizati un efect de explozie in care geometria este afectata ​de gravitatiesimilar cu cea din imaginea de mai jos+Un prim exemplu este reprezentat de situația în care într-o grilă 2D se poate păstra informație de culoare în componentele rgb și o informație binară în componenta alpha. Această ultimă informație se poate interpreta astfel încât, pentru un pixel prelucrat de un program de tip fragment ​shader, pentru ​care pe baza coordonatelor ​de textură se eșantionează valoarea 1, i se asociază pixelului culoarea dată de atributul de ieșire a programului de tip fragment shaderiar unui pixel pentru care se eșantionează valoarea 0 nu i se asociază culoarea dată de atributul de ieșire. Un astfel de exemplu este în imaginea de mai jos, unde în partea stângă se prezintă doar valoarea componentei alpha.
-{{ :​ppbg:​laboratoare:​geometry-shader1.gif?600 |}}+
  
-Utilizati ecuatia miscarii:+{{ egc:laboratoare:​lab9texturephoto5.png?​600 |}}
  
 +Pentru a nu asocia pixelului culoarea de la atributul de ieșire al programului de tip fragment shader, se poate folosi directiva ''​discard'':​
  
-$$ +<code cpp> 
-P_0 + V \cdot t + \frac{1}{2\cdot \cdot t^+vec4 color texture2D(texture_unit,​ texture_coord);​ 
-$$+ 
 +if(color.a < 0.5) { 
 +    discard; 
 +} 
 +</​code>​ 
 + 
 +Directiva ''​discard''​ oprește programul de tip fragment shader la momentul apelului ei. 
 + 
 +<note tip> 
 +În codul de mai sus, s-a folosit directiva ''​discard''​ pentru valori ale componentei alpha mai mici decât valoarea 0.5 pentru a se ține cont de posibilitatea utilizării unui proces de eșantionare liniară, ce se aplică și pentru componenta alpha. 
 +</​note>​ 
 + 
 +Un alt exemplu de aplicare a utilizării obitectelor de tip textură pentru a stoca informații generice este utilizarea unei grile 2D pentru a păstra un deplasament în spațiul obiectului. Astfel, la desenarea unui plan, se poate modifica componenta y a coordonatei fiecărui vârf pe baza informației din grila 2D, proiectată pe toată suprafața planului. Un exemplu de imagine ce păstrează o astfel de informație se poate vedea mai jos: 
 + 
 +{{ ppbg:​laboratoare:​heightmap.png?​200 | }
 + 
 +Rezultatul deformării unui plan pe baza imaginii de mai sus este: 
 + 
 +{{ ppbg:​laboratoare:​terrain.png?​600 | }} 
 + 
 +===== Cerințe laborator ===== 
 + 
 +  - 0.1p - Utilizați obiecte de tip textură pentru desenarea geometriei:​ 
 +    * Completați metoda ''​CreateTexture()''​ pentru ​crea un obiect de tip textură. 
 +    * Completați metoda ''​RenderSimpleMesh()''​ pentru a asocia o unitate de texturare fiecărei din cele obiecte de tip textură și pentru a transmite la programul de tip shader numerele unităților de texturare asociate. 
 +    * Completați în fișierul ''​LabShader.VS.glsl''​ calcularea valorii atributului de ieșire pentru coordonata de textură. 
 +    * Completați în fișierul ''​LabShader.FS.glsl''​ eșantionarea informației dintr-un singur obiect de tip textură. 
 +    * Utilizați directiva ''​discard''​ pentru a opri programele de tip fragment shader pe baza valorii componentei alpha eșantionate. 
 +    * În metoda ''​Init()'',​ specificați coordonatele de textură ale vârfurilor unui patrulater. Aveți în vedere că directiva ''​glTexImage2D()''​ asociază primele celule din memorie cu linia de jos a grilei 2D, astfel că este necesară inversarea componentei y a coordonatelor de textură. 
 +    * Până în acest punct, rezultatul pe care ar trebui să îl obțineti este următorul: {{ ppbg:​laboratoare:​textures.png?​600 | }} 
 +  - 0.05p - Completați metoda ''​CreateStrippedTexture()''​ pentru a crea conținutul unei grile 2D ce conține o informație de culoare cu trei componente, rgb, în fiecare celulă. Grila 2D trebuie să conțină același triplet (r, g, b) în toate celulele ce se află pe aceeași linie. Altfel spus, toate valorile de culoare de pe o linie sunt identice. Culoarea celulelor unei linii este aleasă aleatoriu. Un exemplu de rezultat posibil este: {{ ppbg:​laboratoare:​striped.png?​300 | }} 
 +  - 0.05p - Creați un alt program de tip shader în care să eșantionați informația din două obiecte de tip textură și atribuiți la final o culoare obținută prin combinarea celor două culori eșantionate:​ 
 +    * Utilizați programul de tip shader pentru desenarea cubului din partea dreaptă. 
 +    * Trimiteți în atributul de ieșire al programului de tip fragment shader culoarea obținută prin interpolare liniară între cele două culori eșantionate:​ <code glsl>​vec3 color = mix(color1, color2, 0.5f);</​code>​ 
 +  - 0.05p - Creați un alt program de tip shader în care să creați un efect de rotație a globului pământesc doar prin modificarea coordonatelor de textură: 
 +    * Utilizați programul de tip shader pentru desenarea sferei. 
 +    * Utilizați timpul aplicației:​ ''​Engine::​GetElapsedTime()''​. 
 +  - 0.05p - Creați un alt program de tip shader în care să modificati coordonatele vârfurilor pe baza unei hărți de inălțimi:​ 
 +    * Utilizați programul de tip shader pentru desenarea planului din depărtare. 
 +    * Harta de înălțimi este stocată în cel de-al doilea obiect de tip textură. 
 +    * În atributul de ieșire al programului de tip fragment shader, trimiteți o culoare obținută prin interpolare liniară între valorile eșantionate din obiectul de tip textură ce pastrează informație de culoare și cel ce păstrează informație de înălțime. 
 +    * Rezultatul obținut este cel de la secțiunea Stocarea unor informații generice, de mai sus. 
 + 
 +Bonus: Utilizați imaginile ''​lab08/​images/​snow.png''​ și ''​lab08/​images/​water.png'',​ împreună cu valoarea de înălțime a fiecarui pixel, pentru a obține rezultatul de mai jos. Observați că trecerea de la zona de apă la cea de pământ este graduală. Același lucru este valabil și pentru trecerea de la zona de pământ la cea de zăpadă :) . 
 + 
 +{{ ppbg:​laboratoare:​terrain2.png?​600 | }}
  
-unde V este o directie de miscare specifica fiecarui triunghi :), iar a este vec3(0, -1, 0). Puteti utiliza si alte valori pentru acceleratia gravitatilonala. t este timpul animatiei. Aveti in vedere ca triunghiurile nu coboara sub valoare 0 pentru componenta y. Animatia se reseteaza dupa un anumit timp. 
ppbg/laboratoare/08.1701896772.txt.gz · Last modified: 2023/12/06 23:06 by andrei.lambru
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