Laboratorul 02

Suprafețe generate

Î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:

  • Un generator, adică o geometrie explicit definită pe baza căreia are loc procesul de generare
  • Un algoritm de generare. Acesta poate fi bazat pe rotație, translație sau pe orice fel de curbă definită prin puncte de control (ex: Bezier, Hermite, etc)

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.

Diferite tipuri de instanțiere

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 1540 de 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, 1540);

Instanțierea explicită se face în shader, generând geometrie nouă prin comenzi glsl, în acest caz prin comenzi de geometry shader:

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:

  1. Obiectul generator (prima linie neagră din stânga)
  2. Obiectul nou generat (2 instanțe ale generatorului și topologie de legatură între linii)
  3. Suprafața finală generată

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:

Suprafețe de translație

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:

Suprafețe de rotație

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.

Curbe și suprafețe de formă liberă

Curbele și suprafețele de formă liberă sunt generate plecând de la niște puncte de control și generând alte puncte pe baza acestor puncte de control, care apoi sunt legate prin topologie pentru a crea suprafața. Există mai multe tipuri de curbe de control: Hermite, Bezier, etc. Dacă folosim câte o curbă de control pentru fiecare dimensiune, obținem metode de generare de suprafețe (petice), de volume sau de forme multidimensionale. În acest laborator vom lucra cu o curba de control Bezier, dar vom descrie pe scurt și un petic Bezier.

Formal, o curbă Bezier este construită pe baza a N puncte, numite puncte de control. Ecuația unui punct generat, pe baza acestor puncte de control, este:

Unde B(t) este noul punct generat, iar t reprezint distanța parametrică între primul punct de control și ultimul punct de control.

În cazul comun, în care N = 4, ecuația devine:

O reprezentare vizuală a procesului de generare de puncte pe baza punctelor de control:

unde punctele albe sunt punctele de control, iar punctele roșii sunt cele generate.

Procesul poate fi extins cu ușurință la 2 dimensiuni prin utilizarea unei petic Bezier. În cazul particular, dar comun al unui petic cu 16 puncte (4×4), acesta poate arăta astfel:

Cerințe laborator

  • În laborator, geometria suport pentru curbă este deja definită. Există două tipuri de instanțieri:
    • Instanțierea implicită, facută cu comanda glDrawElementsInstanced, care este deja implementată și care generează geometria suport de N ori
    • Instanțierea explicită, care va fi implementată în geometry shader.
  • Geometria suport trimisă către shader este o linie, ce leagă primul și ultimul punct de control. Punctele de control sunt accesabile în geometry shader sub numele control_p1, control_p2, control_p3, control_p4.
  1. Trimiteți către shader numărul de puncte generate pe o curbă bezier (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).
  2. Geometria suport va fi în primul rând folosită pentru a genera o curbă de tip Bezier. Pentru acest lucru se vor genera de mână în geometry shader mai multe puncte (no_of_generated_points) pentru care se va evalua curba Bezier.
  3. Se vor genera instanțe deplasate ale curbei bezier folosind translații sau rotații
  4. Pentru două curbe adiacente, se vor genera triunghiuri, ce vor lega geometria generată a instanței curente de geometria generată a instanței următoare, generată prin translație sau rotație (practic se vor lega cate 2 triunghiuri pentru fiecare 2 puncte corespondente de pe 2 curbe - vedeți figura de mai jos). Astfel, plecând de la curbe Bezier, se va crea o suprafață. Modificați output-ul GeometryShader-ului astfel încât să trimita mai departe triangle_strip pentru a procesa corect triunghiurile.

spg/laboratoare/02.txt · Last modified: 2023/09/29 13:39 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