Praćenje zraka svjetlosti

Praćenje zraka svjetlosti (engl. ray tracing) jedan je od algoritama globalnog osvjetljenja koji se u današnje vrijeme koristi za stvaranje računalnih slika visokog stupnja realističnosti.

U osnovi, ideja je imitirati način prostiranja svjetlosti kroz prostor. Ako je medij prostiranja homogen i izotropan, putanje svjetlosti su pravci, kao što je pokazano ovdje ???. Dakle, problemu bi mogli pristupiti ovako: krenuvši od nekog izvora svjetlosti pratili bismo jednu od zraka (roj fotona) na njenom putu kroz prostor prilikom čega bi u određenom vremenskom trenutku ona došla do dioptrijske plohe (dioptar je granica između dva prozirna, homogena i izotropna sredstva) i pritom se jedan njen dio reflektirao, drugi refraktirao, a treći apsorbirao, a u slučaju da ploha nije dioptrijska jednostavno bismo zanemarili lom svjetlosti. Sada bi pratili obje novonastale zrake i ponavljali postupak za svako presijecanje dioptrijske plohe sve dok neka od zraka ne bi došla do leće kamere ili oka promatrača. Samo takve zrake koje u konačnici prolaze površinom leće ili oka doprinose sintetiziranoj slici. Postupak bi trebalo ponoviti za svaku zraku odaslanu od odabranog izvora, i isto učiniti za sve ostale izvore svjetlosti u sceni.

Ovakav bi postupak bio računalno rasipan kad bi se pokušao u ovakvom obliku provesti. Stoga, u cilju smanjenja potrebnih izračuna, današnji algoritmi provode tzv. raycasting, u kojem se zrake svjetlosti odašilju iz leće kamere ili oka promatrača u svim smjerovima omeđenim plohama vidnog polja. S obzirom na to da je konačan rezultat svih grafičkih algoritama dvodimenzionalan raster, tj. obična digitalna slika, broj takvih zraka proporcionalan je razlučivosti i u svakom slučaju, konačno velik.

Opis scene

uredi
 
Slika 1. Ilustracija CSGa

Umjetni 3D okoliš se redovno sastoji od liste osnovnih geometrijskih oblika (primitiva), koji su uglavnom jednostavni geometrijski objekti poput mnogokuta, sfera, čunjeva, itd. Ipak, postoje i mnogo složeniji primitivi, poput parametarskih ploha (Bezier ili NURBS), subdivizijskih ploha, ISO-ploha, a i općenitih algebarskih ili implicitno zadanih ploha. Praćenje zraka svjetlosti je u stanju baratati i s veoma složenim konstrukcijama poput CSG (Constructive Solid Geometry), fraktala, te rekurzivno i proceduralno definiranih objekata. Zapravo, kao primitivan geometrijski oblik zrako-pratilačkog algoritma može stajati bilo kakva geometrijska konstrukcija za koju je moguće izračunati točku presijecanja s pravcom.

Upravo se ta osobina praćenja zraka, da je u stanju baratati s gotovo proizvoljnim primitivnim geometrijskim oblicima drži kao jedno od njegovih najvažnijih svojstava, jer se i najsloženiji geometrijski objekti mogu prikazati na zaslonu bez potrebe njihovog aproksimiranja trokutima, dok se istovremeno zadržava maksimalna preciznost bez pojave artefakata diskretizacije, koji su veoma česti kod algoritama ograničenih na trokute ili mnogokute.

Algoritam praćenja zraka

uredi

Nalaženje najbližeg objekta pogođenog zrakom zahtijeva presijecanje zrake s primitivnim geometrijskim oblicima koji sačinjavaju scenu. Očito je da bi naivan pristup ovom problemu presijecanjem svake odaslane zrake sa svakim objektom u sceni bio neprihvatljivo skup sa stanovišta brzine izvođenja, osim za možda neke najtrivijalnije slučajeve. Stoga, u cilju ubrzanja ovog postupka grade se optimizacijske prostorne strukture koje velikim dijelom eliminiraju nepotrebna presijecanja.

Ideja «ispaljivanja» zraka za potrebe računalnog slikotvorstva datira još od 1968. kad ju je prvi uveo Arhtur Appel, kao alternativnu metodu za rješavanja problema uklanjanja zaklonjenih površina kod renderiranja krutih objekata. Da bi se izračunala dvodimenzionalna slika trodimenzionalnog okoliša, zrake se stvaraju iz virtualne kamere (oka) i usmjeravaju kroz svaki pixel projekcijske ravnine i prate se kroz scenu sve dok ne dosegnu najbliži objekt. Boja ovog objekta i njegovo osvjetljenje se određuje na temelju svojstava objekta i njegova položaja u sceni.

Nadalje, isti koncept odašiljanja zraka se može iskoristi za određivanje «testa vidljivosti» kako bi se dani objekt osjenčalo. Primjerice, sjene se mogu iscrtati tako da se prema svakom od izvora svjetlosti odašilju tzv. zrake sjene koje provjeravaju da li je dani izvor svjetlosti zaklonjen iz gledišta točke presjecišta.

Osim primarnih zraka prve generacije, u suvremenim izvedbama zrako-pratilačkih algoritama neizbježne su i sekundarne zrake druge, treće, do proizvoljno daleke generacije. Naime, njima se simuliraju pojave refleksije i loma opisane osnovnim zakonitostima geometrijske optike. Iako se na prvi pogled možda doima kao veoma složen proces, on je konceptualno, a i programski gledano veoma jednostavan. Glavni razlog tomu je što se ovaj postupak može veoma koncizno opisati u obliku rekurzije, na način koji je predstavljen u sljedećem pseudokodu:


Za svaki pixel na ekranu {
       Stvori svjetlosnu zraku iz ishodišta (oka) prema središtu pixela
       Postavi NajbližaTočka na BESKONAČNOST i NajbližiObjekt na NULL
       Za svaki objekt u sceni {
             Ako zraka svjetlosti presijeca ovaj objekt {
                     Ako je udaljenost presjecišta (d) od ishodišta manja od NajbližaTočka {
                             Postavi NajbližaTočka na d
                             Postavi NajbližiObjekt na ovaj objekt
                     }
             }
       }
       Ispuni pixel bojom pozadine
       Ako je NajbližiObjekt=NULL {
               Okončaj proceduru sjenčanja za ovi pixel
       } 
       Inače {
            Za svaki izvor svjetlosti u sceni {
                       Stvori zraku iz točke presjecišta prema izvoru svjet.
                       Za svaki objekt u sceni {
                             Ako zraka svjetlosti presijeca ovaj objekt {
                                       Umanji intenzitet primljenog svjetla na temelju koeficijenta propusnosti objekta
                              } 
            }//petlja objekata
            Izračunaj percipiranu boju presjecišta definiranog s NajbližiObjekt i NajbližaTočka na temelju ukupnog dolaznog                                        
            svjetlosnog zračenja iz izvora korištenjem neke od funkcija sjenčanja;
            Dodaj tu boju vrijednosti pixela
            }//petlja izvora
            Ako je dubina rekurzije manja od predefinirane {
                      Ako je površina reflektivna, stvori zraku refleksije; rekurzija; 
                            Dodaj povratnu vrijednost vrijednosti pixela
                      Ako je površina prozirna, stvori zraku loma; rekurzija
                            Dodaj povratnu vrijednost vrijednosti pixela
            }
       }
}

Naravno, rekurziju ne možemo vršiti u nedogled, već ju obično ograničavamo na neki nivo dubine koji „na žalost“ nije dostatan da svaku zraku ispratimo do njenog izvora svjetlosti, ali ipak pruža zadovoljavajuću kvalitetu slike uz prihvatljive performanse.

Očigledno je da ovakav algoritam može simulirati samo svjetlosne putanje oblika LDS*E. Naime, kada zraka svjetlosti naiđe na difuznu plohu njena refleksija se ne može opisati jednostavnim stvaranjem nove refleksijske zrake, jer po definiciji difuzna površina reflektira u svim smjerovima ravnomjerno. Ono što bi trebalo učiniti je izračunati doprinose svih ostalih površina u sceni, kako onih koje sačinjavaju izvore svjetlosti (izravno osvjetljenje) tako i onih koje su njima osvijetljene kao posljedica izravne ili posredne izloženosti (neizravno osvjetljenje), kao što to čine algoritmi izračenja.