This is an old revision of the document!
În multe cazuri, putem cunoaște propietățile unei suprafețe fără a-i cunoaște geometria explicită. Putem genera această suprafață folosind o geometrie generatoare și un proces de generare. În acest laborator, vom explora câteva din metodele de generare existente.
Orice suprafață generată are:
Procesul de generare decurge astfel: întâi se desenează geometria generator, pe baza căreia va fi construită suprafața generată. După aceasta, se desenează un număr de instanțe ale geometriei generator, fiecare transformată de funcția de generare într-un mod progresiv. Rezultatul final este obținut prin combinarea topologică a acestor instanțe.
Instanțierea reprezintă un mecanism prin care se amplifică numărul de primitive trimise la banda grafică. Această amplificare este fie explicită (programată de utilizator în shader), fie implicită (generată prin comenzi OpenGL).
Pentru a instanția implict geometrie, există comanda:
glDrawElementsInstanced(topologie, nr_indecsi, tip_data, offset, instante).
De exemplu, dacă aș dori să desenez de 15 ori (instanțe) un obiect cu 99 de indecși, format din triunghiuri din buffer-ul de indecși, legat curent la banda grafică, atunci comanda ar fi:
glDrawElementsInstanced(GL_TRIANGLES, 99, GL_UNSIGNED_INT, 0, 15);
Instanțierea explicită se face în shader, generând geometrie nouă prin comenzi glsl, în acest caz prin comenzi de geometry shader:
for (int index = 0; index < 15; index++) { gl_Position = P*V*M*vec4(p1, 1); EmitVertex(); gl_Position = P*V*M*vec4(p2, 1); EmitVertex(); gl_Position = P*V*M*vec4(p3, 1); EmitVertex(); EndPrimitive(); }
Instanțirea oferă posibilitatea ușoară de a crește rapid numărul de obiecte din scenă, dacă obiectele sunt identice. Ex: copaci, tile-uri de teren, unități într-un rts, etc.
Pentru a lucra cu suprafețe de translație, rotație și/sau interpolare, vom folosi instanțiere. Totuși, chiar dacă avem N instanțe de geometrie generator, nu avem topologia necesară pentru a lega instanțele, deoarece generatorul este o curbă (topologie 2D), iar suprafața generată necesită topologie 3D.
Din figură se observă clar cum avem mai multe tipuri de obiecte:
Dacă nu am fi folosit acest proces, atunci prin instanțiere am fi obținut liniile instanțiate, dar nu și topologia de legatură între linii, adică exact ca în următoarea imagine:
O suprafață de translație este o suprafață generată prin instanțierea unui obiect generator. Fiecare instanță a generatorului suferă o transformare de translație. O suprafață de translație poate fi definită prin instanțierea unui generator cu fiecare instanță translatată progresiv dupa o funcție.
Un exemplu de suprafață translatată este:
O suprafață de rotație este o suprafață generată prin instanțierea unui obiect generator. Fiecare instanță a generatorului suferă o transformare de rotație. Aceasta poate fi definită prin instanțierea unui generator cu fiecare instanță rotită progresiv dupa o funcție.
control_p1
, control_p2
, control_p3
, control_p4
.
no_of_generated_points
) și controlați de la tastatură atât acest număr (no_of_generated_points
), cât și numărul de instanțe (no_of_instances
).GeometryShader.glsl
pentru a desena o curbă Bézier pe baza a 4 puncte de control.line_strip
, prin emiterea mai multor vârfuri ale căror poziții se obțin prin eșantionarea curbei Bézier.GeometryShader.glsl
pentru a desena o suprafață de translație, pe baza curbei Bézier obținute anterior.triangle_strip
, prin emiterea mai multor vârfuri ale caror poziții se obțin prin eșantionarea a două curbe Bézier, alăturate.instance
pentru a translata banda desenata pe baza numarului de ordine al instanței desenate.GeometryShader.glsl
pentru a desena o suprafață de rotație, pe baza curbei Bézier obținute anterior.triangle_strip
, prin emiterea mai multor vârfuri ale căror poziții se obțin prin eșantionarea a două curbe Bézier, alăturate.instance
pentru a roti banda desenată pe baza numărului de ordine al instanței desenate.