|
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);
|