Miran Brajša

miran.brajsa@fer.hr

Seminar iz računalne grafike

DOT3 Preslikavanje izbočina

Tangentni prostor

Računanje vektora osvjetljenja - tangentni prostor

 

Većina algoritama koji se koriste za izračunavanje sjenčanja zahtjevaju proračun osvjetljenja za svaku točku modela. Proračun je neophodan jer nam pruža informaciju o načinu na koji svjetlost utječe na površinu svakog od poligona. Čak i u slučaju da je izvor svjetla na sceni statičan, potrebno je ponovno načiniti proračun osvjetljenja kod svakog iscrtavanja scene kako zbog pomaka tako i zbog različitih rotacija modela na njoj.

Kako bi dobili relativno osvjetljenje svake točke modela, potrebno je znati orijentaciju svake površine koja tu točku sadrži, odnosno orijentaciju svakog poligona. Iz razloga što moramo voditi računa o koordinatama bump teksture, potrebno je dodati još dva vektora koja nam pomažu kod definiranja ravnine. To su tangenta i druga tangenta (koristi se i naziv binormala). Prostor njima definiran nazivamo tangentnim prostorom ( eng. tangent space ). Taj je prostor, u stvari, skup od tri vektora koja koristimo kako bi svakoj točki mogli definirati njezin vlastiti koordinatni sustav. Odabir koordinatnih osi u glavnom se vrši na sljedeći način. Tangenta se odabire kao vektor paralelan sa poligonom, normala je vektor okomit na poligon dok se binormala računa kao vektorski produkt dvaju prije spomenutih vektora. Slika 6. prikazuje tangentni prostor triju točaka koje određuju trokut.

Prva stvar koju moramo napraviti, je izračunati tangentni prostor svih točaka koje određuju model. To se računa samo jednom, pa je preporučljivo da se sav račun obavi u inicijalizacijskom dijelu programa.

 


Slika 6: Tangentni prostor

 

Prije nego što krenemo na postupak računanja tangentnog prostora potrebno je objasniti neke osnovne stvari o koordinatama tekstura. Koordinatni sustav teksture sastoji se od dvije koordinatne osi: U i V. Vektori T i B, odnosno tangenta i binormala usmjereni su u pravcu povećanja U i V koordinata respektivno.

 

Dan je postupak računanja tangentnog prostora u pseudokodu:

 

Točke l1, l2 i l3 označavaju relativno osvjetljenje određene točke u modelu, te se njihove x,y i z vrijednosti koriste kako bi se odredila dužina vektora T i B u tim smjerovima, odnosno jačina osvjetljenja tih točaka pri korištenju DOT3 tehnike. Krajnji rezultat podjeli se prvom komponentom vektorskog produkta, jer tražimo projekciju tog pravca na pripadnu ravninu. Postupak traženja vektora T i B, kao i postupak traženja normale određene točke sastoji se u prolazu kroz sve poligone modela i ispitivanju je li točka za koju tražimo određeni vektor sadržana u tom poligonu. Ako je, računamo i njegov utjecaj na istu.

 

zaSvakiPoligonModela{

            float x,y,z;

            tocka l1,l2,l3;

           

            //x označava vektorski produkt

           

            (x, y, z) = (l2.x-l1.x, l2.u-l1.u, l2.v-l1.v) x (l3.x-l1.x, l3.u-l1.u, l3.v-l1.v)

           

            ako je(x != 0){

                        normaliziraj(x,y,z);

                        l1.Tx += y/x;

                        l1.Bx += z/x;

                        l2.Tx += y/x;

                        l2.Bx += z/x;

                        l3.Tx += y/x;

                        l3.Bx += y/x;

            }

           

            (x, y, z) = (l2.y-l1.y, l2.u-l1.u, l2.v-l1.v) x (l3.y-l1.y, l3.u-l1.u, l3.v-l1.v)

           

            ako je(x != 0){

                        normaliziraj(x,y,z);

                        l1.Ty += y/x;

                        l1.By += z/x;

                        l2.Ty += y/x;

                        l2.By += z/x;

                        l3.Ty += y/x;

                        l3.By += y/x;

            }

           

            (x, y, z) = (l2.z-l1.z, l2.u-l1.u, l2.v-l1.v) x (l3.z-l1.z, l3.u-l1.u, l3.v-l1.v)

           

            ako je(x != 0){

                        normaliziraj(x,y,z);

                        l1.Tz += y/x;

                        l1.Bz += z/x;

                        l2.Tz += y/x;

                        l2.Bz += z/x;

                        l3.Tz += y/x;

                        l3.Bz += y/x;

            }

}

zaSvakuTockuModela{

            normaliziraj(T);

            normaliziraj(B);

           

            N = T x B;

}

 

Pretpostavka je da struktura/klasa tocka sadrži sljedeće elemente:

 

struct tocka{

            float x,y,z;                                //koordinate točke u 3D prostoru

            float u,v;                                  //2D koordinate teksture

            float Nx,Ny,Nz;                       //vektor normale

            float Tx,Ty,Tz;             //vektor tangente

            float Bx,By,Bz;            //vektor binormale

};

 

Sada kad smo izračunali prostore svih točaka u modelu, ti se vektori mogu iskoristiti za proračun osvjetljenja svake točke. Međutim, vektori T, N, B kao i vektor L ( usmjereni vektor izvora svjetlosti ) moraju biti definirani unutar istog 3D prostora, prije nego što translatiramo vektor L ovisno o svakoj točki. Kako je vektor L obično definiran unutar prostora scene, moramo ga transformirati u lokalni prostor točke ( eng. local space ), koristeći inverznu matricu. To je puno učinkovitije i brže rješenje nego transformacija svih vektora tangentnog prostora u prostor scene!

Jednom kada su svi vektori potrebni za proračun osvjetljenja točke definirani unutar istog 3D prostora, možemo izračunati boju/osvjetljenje svake točke prema sljedećoj jednadžbi:

 

 

  je vektor koji definira osvjetljenje odnosno boju određene točke modela. Još nam je jedino preostalo prilagoditi to osvjetljenje kako scena ne bi bila previše tamna. Zbog toga ćemo sve tri vrijednosti vektora boja pomnožiti sa 0.5 i time dobiti difuznu komponentu osvjetljenja. Kako bi dobili osvjetljenje točke u intervalu od 0 do 1 potrebno je dodati svakoj vrijednosti 0.5 što predstavlja ambijentalnu komponentu (označeno crvenom bojom).

 

bojax = 0.5f + bojax * 0.5f;

bojay = 0.5f + bojay * 0.5f;

bojaz = 0.5f + bojaz * 0.5f;

glColor3f(bojax, bojay, bojaz);