Literatura

  1. Shreiner D., Woo M., Neider J., Davis T. (2007). OpenGL: vodič za programere. Beograd: Kompjuter biblioteka.
  2. Wright Jr. R. S., Lipchak B., Haemel N. (2007). OpenGL SuperBible, 4. izdanje
  3. Arbanas M. (2013). Postupci ostvarivanja sjene – Diplomski rad. Dostupno 15.12.2013. na poveznici
  4. Rogulja Ž. (2007). Napredni vizualni aspekti virtualnih likova – Diplomski rad. Dostupno 15.12.2013. na poveznici
  5. The Industry's Foundation for High Performance Graphics. OpenGL Shading Language. Dostupno 15.12.2013. na poveznici

Prezentacija

Prezentacija korištena prilikom obrane projekta može se preuzeti ovdje.

Tko želi znati više

Za sve koji žele saznati nešto više, umjesto ovakvog sažetog pregleda mogu pročitati podugačak tekst koji može dati i malo širu sliku o svemu.

Iscrtavanje sjena pomoću spremnika dubine (OpenGL)

Princip rada odnosno obavljanja operacija OpenGL API-a se može opisati kao klijent-poslužitelj arhitektura. Aplikacija (klijent) izdaje OpenGL naredbe koje interpretira i procesira implementacija OpenGL-a (poslužitelj). OpenGL naredbe su uvijek procesirane onim redom kojim su stigle na poslužitelj. Procesiranje naredbi izvan redoslijeda nije dozvoljeno. OpenGL je dizajniran kao automat odnosno stroj stanja koji služi za aktualiziranje sadržaja slikovnog međuspremnika. Proces pretvaranja geometrijskih primitiva, slika u točke na ekranu je kontroliran velikim brojem parametara koji poprimaju unaprijed definirane vrijednosti. Mali broj parametara na OpenGL poslužitelju ima samo dva stanja, odnosno stanja uključeno ili isključeno. Postavljanje u jedno od dva stanja se obavlja naredbom glEnable kojoj se dodaje simbolična konstanta. OpenGL održava na poslužiteljskoj strani stog u koji se mogu pohraniti ili iz njega pribaviti jednu ili sve definirane vrijednosti parametara.

OpenGL Shading Language je jezik kojim se programiraju vertex i fragment procesor, odnosno programiraju programabilni dijelovi grafičkog protočnog sustava OpenGL-a. Jezik vuče korijene iz programskog jezika C i vrlo je sličan Pixarovom enderManu. Bogat je različitim tipovima i strukturama podataka, među kojima su vektori i matrice kako bi kod bio što jednostavniji za tipične grafičke operacije u 3D-u. Mehanizmi preopterećenja funkcije i mogućnost deklaracije varijable onog trenutka kada je potrebna, a ne na početku bloka, posuđeni su iz jezika C++. Podržane su petlje, proceduralni pozivi, uvjetni izrazi te mnoštvo ugrađenih funkcija kako bi se olakšala implementacija shading algoritama.

Sjena je prostor gdje je izvor svjetla blokiran nekim objektom. U računalnoj grafici sjene znatno povećavaju realizam slike. Sjene daju osjećaj pozicije objekta u odnosu na druge objekte. Bez sjena ponekad ne postoji dojam gdje se objekt nalazi u sceni. Postoje razne tehnike iscrtavanja sjena, od fotorealističnih do jednostavnih manje preciznih sjena. Fotorealistične sjene se postižu algoritmima praćenja zrake (eng. ray-tracing), čime se prati stvaran put koji bi svjetlo prešlo od izvora do pogleda. U iscrtavanju u stvarnom vremenu algoritmi praćenja zrake nisu dovoljno brzi te se zahtijevao lakši način iscrtavanja sjene. Projektivne sjene su jedan od jednostavnih načina u kojem bi se projektirao objekt na ravnu površinu te bi tako stvorio sjenu. Projektivne sjene rade za ravne površine, no ne i za zakrivljene koje primaju sjenu. Teksture sjena su drugi način kod kojeg bi se generirala slika objekta koji baca sjenu iz pogleda svjetla te bi se ta tekstura projektirala na objekt koji prima sjenu. Ovime se postižu sjene i na zakrivljenim površinama, no problem se javlja kada objekt treba bacati sjenu na samog sebe.

Dvije najčešće tehnike generiranja sjena su:

  • tehnika mapa sjena (eng. shadow mapping)
  • tehnika volumnih sjena (eng. shadow volumes)

Mape sjena (eng. shadow mapping) je tehnika prikazivanja sjena korištenjem dubinske mape generirane iz izvora svjetlosti. Tehniku je osmislio Lance Williams 1978. godine. Tehnika se temelji na generiranju dubinske slike, odnosno mape iz pogleda svjetla u njenom korištenju prilikom generiranja slike iz pogleda kamere u nekoj sceni. Prvotno se pogled na scenu postavi u izvor svjetla te se generira samo dubinska mapa, pri čemu nije potrebno generirati ostale mape kao što su na primjer mapa boje. Takvu mapu potrebno je spremiti i koristiti pri ponovnom generiranju slike, ali ovog puta iz pogleda kamere. Prilikom novog generiranja slike te nove dubinske mape, uspoređuje se udaljenost pojedinih elemenata slike od svjetla s dubinom odgovarajućih elemenata iz prve dubinske mape. Ukoliko je dubina elementa slike veća od dubine elementa iz prve dubinske mape tada je taj element u sjeni te se u slici iscrtava zasjenjen, dok je inače na svjetlu te se iscrtava osvijetljen. Prije same usporedbe potrebno je još elemente nove slike postaviti u pogled svjetla kako bi usporedba bila točna. Mape sjene su jedan od najčešće korištenih algoritama za generiranje sjena. No, one imaju nedostatke, odnosno možemo reći da imaju neke greške. Najčešće greške su perspektiva pogreška uzrokovanja, akne sjena i ograničenost područja koje je vidljivo iz pogleda svjetla. Perspektivna pogreška uzrokovanja javlja se kada preslikavanje elemenata teksture dubinske mape s elementima slike nije u omjeru 1:1, nego se više elemenata slike preslikava na isti element teksture dubinske mape. Uzrok ovome je ograničena rezolucija dubinske mape i uočljiviji je na elementima slike koji su bliže kameri. Takvi elementi slike su i prostorno bliži te se više njih preslikava na isti element dubinske mape. Što su elementi slike dalji, to oni pokrivaju veći prostor scene i manji broj ih se preslikava na isti element dubinske mape. Jedan pristup rješavanju ovog problema bio bi povećavanje rezolucije dubinske mape. No međutim, to nije dobro rješenje jer narušava brzinu iscrtavanja, a artefakti, iako u manjoj mjeri, ponovno mogu biti vidljivi. Drugi pristup bio bi da se iscrtavanje dubinske mape ograniči na prostor koji je trenutno vidljiv iz pogleda kamere, odnosno da mapa usko obuhvati samo one objekte u sceni koji su trenutno vidljivi, smanjujući kut pogleda i poklapajući projekciju pogleda svjetla s prostorom koji vidi kamera. Tako se postiže veća rezolucija sjene za vidljive objekte, dok se ne iscrtavaju oni objekti koji ionako neće biti vidljivi. Taj pristup se naziva perspektivne mape sjena u prostoru svjetla. Ovime se postižu mnogo bolji rezultati, posebno u području koje je bliže kameri gdje je potreban gušći raspored elemenata dubinske mape. Druga greška koja se javlja jesu akne sjena. One se javljaju kada udaljenost od svjetla elementa dubinske mape i odgovarajućeg elementa iz scene nisu jednake nego približne. Zbog ograničene preciznosti iz spremnika te diskretizacije dubine za područje koje pokriva element, vrijednost udaljenosti može odstupati od stvarne udaljenost te se za taj element s greškom utvrđuje da li je u sjeni. Jednostavno rješenje je da se pri usporedbi vrijednosti iz dubinske mape i stvarne udaljenosti doda malo odstupanje, čime se zapravo pomiče udaljenost dubinske mape od izvora svjetla. Vrijednost odstupanja treba biti malog iznosa, jer u protivnom sjene mogu biti odmaknute od objekta. Ovo rješenje uklanja akne s ravnih površina, no na zakrivljenim će se one i dalje pojavljivati. Na zakrivljenim površinama razlika između stvarne udaljenosti i iz dubinske mape je veća od razlike na ravnim površinama te je zbog toga potrebno uvesti i veće odstupanje. No uvođenjem prevelikog odstupanja sjene postaju sve odmaknutije od objekta koji ih stvara te u određenim uvjetima mogu i nestati. Zbog toga dodavanje većeg odstupanja nije poželjno. Uklanjanje akni sa zakrivljenih površina može se postići tako da se u dubinsku mapu iscrtavaju samo oni poligoni objekta koji su okrenuti od svjetla, tj. kojima je normala okrenuta u smjeru u kojem je i vektor od položaja svjetla prema gledištu. U OpenGL-u ovo se može postići s glCullFace(GL_FRONT), čime će se iscrtavati samo stražnji poligoni objekta, a prednji će biti odbačeni. Akne će se i dalje pojavljivati, no sada na stražnjim poligonima koji su okrenuti od svjetla te su već u sjeni. Zadnja greška koja se javlja je ta što su sjene ograničene na područje koje se vidi iz pogleda svjetla. Objekti koji se nalaze izvan pogleda svjetla neće bacati sjenu. Rješenje ovog nedostatka je moguće generiranjem 6 dubinskih mapa iz 6 različitih pogleda koje tvore jednu prostornu mapu nazvanu eng. cubemap. Za svaku je potrebno imati posebnu matricu koja transformira točke objekta u sceni u koordinate teksture dubinske mape. Odgovarajuća dubinska mapa tada se može odrediti kao ona za koju su vrijednosti transformiranih x i y koordinata teksture u intervalu [0.0, 1.0]. Za sve ostale mape, transformacija pripadajućim im matricama će davati vrijednosti koordinata teksture izvan tog intervala.

Volumne sjene (eng. shadow volumes) je tehnika prikazivanja sjena korištenjem volumena sjene. Tehniku je osmislio Frank Crow 1977. godine. Tehnika se temelji na ekstenziji siluete objekta viđene iz izvora svjetla i detektiranju jesu li objekti unutar tog volumena. Najprije se iscrtava scena samo u dubinski spremnik. Zatim se određuje silueta objekta kakva je viđena iz pogleda svjetla te se točke siluete produžuju dalje od svjetla, a volumen koji je pri tome obuhvaćen je volumen sjene. Taj volumen sjene se iscrtava u spremnik šablone na način da se vrijednost u spremniku šablone povećava pri iscrtavanju prednjeg poligona volumena sjene, a smanjuje pri iscrtavanju stražnjeg poligona. Na taj način se u spremnik šablone iscrtava sjena za koju su u spremniku vrijednosti različite od 0. Zatim se iscrtava scena u spremnik slike za sve one vrijednosti u spremniku šablone koje su jednake 0. Glavna prednost tehnike volumnih sjena u odnosu na tehniku mapa sjena je sprječavanje pojavljivanja perspektivnog aliasinga i akni sjena. Perspektivni aliasing se javlja kada rezolucija mape sjena nije dovoljna te se više elemenata slike preslikava u jedan element mape sjena. Budući da se volumne sjene generiraju za svaki element spremnika šablone, a time i za svaki element slike, perspektivnog aliasinga nema. Akne sjena se u tehnici mapa sjena javljaju zbog nepreciznosti udaljenosti elementa od svjetla dobivene iz pogleda svjetla i udaljenosti dobivene iz pogleda kamere. Kod volumnih sjena test na dubinu se provodi iz istog pogleda, a budući da se volumen sjene proteže u beskonačnost prilikom testiranja na dubinu, neće doći do grešaka. Volumne sjene nisu ograničene na prostor pogleda svjetla kao što je to kod mapa sjena, tj. sjene se mogu generirati za čitav prostor. Problem kod volumnih sjena je što nije moguće napraviti točnu sjenu za objekte s transparentnom teksturom. Budući da se volumen sjene generira iz siluete objekta, transparentne teksture ne utječu na oblik siluete. Zbog toga objekti s transparentnim teksturama (npr. lišće, ograda) neće imati pravilnu sjenu. Objekti koji bacaju sjenu moraju biti potpuno zatvoreni, što nije slučaj kod mapa sjena kod kojih nije od velike važnosti geometrija objekta. Ako objekt nije u potpunosti zatvoren, za otvoreni dio će se također generirati volumen sjene. No, najveći nedostatak volumnih sjena je što je za istu scenu potrebno iscrtati više poligona nego kod mapa sjena. Za volumne sjene su potrebna tri iscrtavanja geometrije, prvi put za iscrtavanje dubinske mape, drugi put za iscrtavanje volumena sjena te treći put iscrtavanje u spremnik slike. Kod mapa sjena potrebna su dva iscrtavanja, jednom za dubinsku mapu iz pogleda svjetla, te drugi put iz pogleda kamere. Zbog toga je iscrtavanje mape sjena brže od volumnih sjena. Volumne sjene također zahtijevaju generiranje volumena sjena, što dodatno usporava iscrtavanje, a posebno ako nisu podržani programi za sjenčanje geometrije, u kojem slučaju se volumeni generiraju na glavnom procesoru.