Laboratorul 04.

Maparea mediului inconjurator

Introducere

Maparea mediului inconjurator reprezinta o metoda prin care putem interoga informatia din jurului unui obiect. Fie ca facem acest lucru pentru reflexii, refractii sau alte efecte mai complicate ideea este aceeasi: de a putea reprezenta intr-un mod eficient mediul inconjurator.

In imaginea de mai sus se poate observa cum o raza ce pleaca din camera se poate descompune in doua traiectorii distinctincte: una reflectata si una refractata. In realitate procesul este mai complicat dar pentru o iluzie vizuala acest model este suficient. Problema interesanta ce este usor de observat in acest desen este problema intersectiilor. Rasterizarea este un proces de intersectie coerent, bazat pe faptul ca intersectia intre primitiva si raster are loc intr-un mod cu localitate in mare masura garantata a fi buna. Problema cu un model bazat pe raze este ca nu mai avem mecanismul de rasterizare pentru a calcula foarte eficient intersectiile. Alternativele sunt raze, ca la ray-tracing, ce duc la un proces foarte costisitor si incoerent din punct de vedere al localitatii spatiale sau aproximari. Una din aceste aproximari se numeste cube mapping.

Ce este un cubemap

Un cubemap este un tip special de textura care este formata din 6 imagini: pozitiv x, negativ x, pozitiv y, negativ y, pozitiv z, negativ z. Aceste 6 imagini reprezinta o impartire a unei sfere in 6 planuri, asa cum poate fi observat in imaginea urmatoare. Un cubemap reprezinta de obiecei culoarea de la mediul inconjurator, pe toate directiile. Deci, un cubemap poate fi perceput ca un set de elemente de tip (directie, culoare). Un cubemap poate fi citit doar cu coordonate de texturare tridmensionale, pentru ca interogam culoarea din harta pentru directia (coordonata de texturare) introdusa. Mai mult cum coordonatele de texturare sunt de fapt directii, ele pot fi si negative.

Formatul in care veti gasi de obiecei acest tip de textura este ca 6 imagini diferite sau ca o imagine cu urmatoarea forma.

Un cubemap este creat la fel ca orice alta textura, cu comanda:

glGenTextures(1, &gl_texture_object);

Cubemapul este legat la banda grafica la un nou punct de legare per unitatea de texturare curent legata, numit GL_TEXTURE_CUBE_MAP:

glBindTexture(GL_TEXTURE_CUBE_MAP, gl_texture_object);

Din punct de vedere al filtrarii procesul este identic cu cel al unei texturi bidimensionale, doar ca se poate folosi si:

glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

care imbunatateste efectele vizuale la filtrarea de la marginea dintre fete. Pentru a introduce date in aceasta textura, se introduc pe rand toate cele 6 imagini, fiecare pe o pozitie specifica:

glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data_posx);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data_posy);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data_posz);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data_negx);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data_negy);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data_negz);

Shadere

Pentru a fi utilizat in shader, un cubemap trebuie legat la banda grafica, proces identic cu cel pentru o textura 2D normala. In schimb, in shader se foloseste un sampler diferit, numit samplerCube care functioneaza doar cu coordonate de texturare tridimensionale.

Pentru a implementa reflectia si refractia se pot folosi functiile de glsl:

reflect( RazaIncidenta, Normala) 
refract( RazaIncidenta, Normala, indexMediuCurent/indexMediuNou)

ce ne ofera directia razei reflectate sau refractate. Dar cum cubemapul reprezinta de fapt o harta de culoare interogata prin directie, putem folosi razele reflectate/refractate din fragment ca si coordonate de texturare pentru a afla culoarea mediului din directia razelor.

Rezultatul final pentru o reflectie poate fi calculat cu:

vec3 culoarefragment = texture(cubemap, reflect(RazaIncidenta, Normala));

Observatii:

  • pentru refractia unei raze din aer (index de refractie 1.0) in apa (index de refractie 1.33) apelul de functie ar fi refract(I, N, 1.0/1.33);
  • raza incidenta vine de la camera la suprafata, nu invers!

Rezultate(reflexie, apoi refractie)

Cerinte laborator

  1. Completati laboratorul cu cod in loc de TODO
spg/laboratoare/04.txt ยท Last modified: 2018/10/14 19:57 by anca.morar
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