VIDI Project X #82:
Ray Tracing renderiranje visokorealistične slike s Vidi X mikroračunalom

Ovaj kôd može poslužiti i kao svojevrstan benchmark kako biste usporedili razne programske metode računanja ili usporedili performanse s drugim mikrokontrolerima.

Sigurno ste čuli za pojam Ray tracing. Možda je prijatelj spominjao da njegova Nvidia grafička sada ima poboljšane Ray tracing mogućnosti. Moguće je da ste se susreli s tim pojmom kada ste promatrali kako su napravljeni specijalni efekti u najnovijem blockbuster filmskom naslovu.
Kako biste mogli razumjeti Ray Tracing, prvo ćemo vam pokušati dočarati svakidašnji prizor. Vid.

 

Ljudsko oko vidi slično kao što to omogućuje Ray Tracing u renderiranoj slici

 

Kako vidi ljudsko oko?

Slika koju ljudsko oko vidi vrlo je sličan Ray tracing renderiranoj slici. Pokušajte razumjeti kako vidimo slike.
Dakle, ljudsko oko u mraku ne vidi ništa. Da bismo vidjeli, potreban nam je izvor svjetlosti. U našem je primjeru glavni izvor svjetlosti lociran desno na slici, a radi se o velikom prozoru.
Zraka svjetlosti koja prolazi kroz taj prozor naići će na stolac te će se odbiti od njega u svim smjerovima, no neće proći kroz sam stolac te će zbog toga manja količina svjetlosti doći do poda koji se nalazi neposredno s lijeve strane stolca. Tu će nastati sjena. Ta sjena nije crna zato što je do tog istog mjesta na podu također došla zraka svjetlosti koja je ušla kroz prozor. Kako je prozor određene dimenzije te kroz njega ulazi beskonačno mnogo zraka svjetlosti, neke sjene su mekše od drugih. One sjene na koje nije stigla velika količina svjetlosti zbog prepreka koje su im se našle na putu, tamnije su i oštrije, poput sjene koju primjećujete ispod sofe.
Zraka svjetlosti može se i prelomiti na više drugih zraka svjetlosti. Takav primjer vidite na staklenom stolu. Zraka svjetlosti koja je došla do sredine stola razlomila se i prošla kroz stol te zbog toga vidimo predmete iza stakla. Knjige. No ista ta zraka odbila se prema kipiću ptice na stolu, te zbog toga vidimo i refleksiju tog kipića na stolu. No kako se radi o zraci koja se razlomila na onu koja je prošla kroz staklo i onu koja se odbila prema kipiću, refleksiju kipića vidimo upola slabije.
Tik pored refleksije kipića na stolu vidimo nešto jasniju refleksiju noćne lampe. Jasnija je jer je i ona sama izvor svjetlosti, te se na tom mjestu gotovo i ne vidi kroz staklo stola.
Nešto dalje, na zidu sobe, nalazi se ogledalo do kojega stiže zraka svjetlosti, odbije se od njega u potpunosti te je stoga slika u ogledalu vjerna originalu tj. nije blijeda.
Dakle, ako ste dobro pazili i shvatili kako ljudsko oko vidi sliku, mogli ste primijetiti da postoji beskonačno mnogo zraka svjetlosti koje dolaze od Sunca i od umjetnih izvora svjetlosti te se odbijaju od površina i prolaze kroz njih.
Jedan mali dio zraka odbije se od raznih površina i završi u našem oku te ih interpretiramo kao sliku, skup boja raspoređen u smislenu cjelinu. Iako je samo sitan dio završio u našem oku, kada beskonačno podijelite s bilo kojim brojem, rezultat je i dalje beskonačno.
Kada bismo pokušali računalu dati da izračuna takve parametre, nikada ne bi mogao računicu privesti kraju upravo zbog tog neizrecivo velikog broja zraka.

 

Grafički prikaz Ray Tracing scene, objekata na sceni te zraka koje pratimo i računamo jesu li u sjeni ili je zraka naišla na objekt

 

Ray Tracing

Kako još uvijek računala nemaju beskonačne resurse za računanje tog neizrecivo velikog broja zraka, dosjetili smo se ograničiti im broj. S obzirom na to da monitor računala ima piksele kojima je ograničen, nije potrebno računati beskonačno puno, nego samo onaj broj zraka koji ima rezolucija našeg monitora.
Kod Vidi X mikroračunala radi se o 320 x 200 pixela koji su raspoloživi na ekranu. Metoda računanja koja ne kreće od izvora svjetlosti, nego kreće sa suprotne strane, od oka promatrača tj. monitora, u ovom se slučaju zove Ray tracing metoda. Takvih zraka na monitoru Vidi X-a ima 64000 te ih samo toliko treba izračunati da bi bila prikazana renderirana realistična slika na ekranu.
Za projekciju scene u određenoj perspektivi, potrebno je za svaku vidljivu točku odrediti koliko svjetlosti dolazi na nju s okolnih objekata i rasvjete. Dakle, zraka kreće s jedne referentne točke projekcije (pozicija kamere) te prolazi kroz prvi piksel ekrana. Nakon toga dolazi do prvog vidljivog objekta na sceni pa je potrebno odrediti osvjetljenje za taj objekt.
Potrebni parametri za izračunavanje osvjetljenja na poziciji zrake su osobine materijala objekta, relativna pozicija objekta na sceni, boja objekta, pozicija i karakteristike izvora svjetlosti te pozicija i orijentacija ravnine gledanja. Tri nove zrake proizlaze iz tog kontakta s objektom. Refleksija, refrakcija i sjena. Dobivene vrijednosti ovise o karakteristikama površine objekta kojeg je zraka pogodila. Reflektirana ili refraktirana zraka, nazvana još i secondary ray (druga zraka) putuje do sljedećeg objekta na sceni ili do izvora svjetlosti te time doprinosi intenzitetu boje piksela primarne zrake.
Ova računica nije toliko komplicirana kako djeluje na prvi pogled, a temelji se na zakonima geometrijske optike.
Kada smo dobili vrijednosti za prvi piksel na ekranu, računanje se nastavlja za sljedeći piksel i dalje dok ne stignemo i do posljednjeg, 64000. pixela.

Praćenje zraka svjetlosti 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

 

Arduino IDE instalcija

Ako već nemate Arduino IDE, instalirajte ga na način opisan na linku

VIDI Project X #91: Arduino IDE – Windows instalacija

 

Instalacija librarya:
Bit će nam potrebni neki libraryiji te ih preuzmite i instalirajte putem Library Managera. Dakle, kliknite na izbornik Alati, a zatim na Manage Libraries…
Sada u tražilicu upišite Adafruit ILI9341. Instalirajte prvu od ponuđenih biblioteka. Otvorit će vam se novi prozor u kojem se nudi instalacija dodatnih biblioteka poput potrebne nam Adafruit GFX Library te stoga kliknite na Install All kako bi se instalirale sve ponuđene biblioteke.

 

 

 

Kod

Ovaj kôd za Ray tracing baziran je na Paul Heckbertovom “business card raytracer” kôdu. Naime, napisao ga je jer mu je cilj bio proizvesti kôd za raytracer koji stane na poleđinu posjetnice (vizitke).
Za one koji nikada nisu čuli za taj izazov, to je poznati izazov iz područja računalne grafike koji je započeo prije nešto više od 35 godina, 4. svibnja 1984.
Impresivno je što Ray tracing stane u tako malo prostora. Doduše, kôd koji vam donosimo napisan je razumljivo te je dobro iskomentiran kako biste što lakše mogli proučavati njegove dijelove te se igrati s njima.

Kôd preuzmite s VidiLABovog GitHuba s adrese https://github.com/VidiLAB-com/Vidi-X/tree/master/TFT22_raytrace

 

 

U glavnoj skici programa pronaći ćete linije koje pozivaju funkciju za iscrtavanje ekrana

doRaytrace(1,320,240,1); // full 320x240 jedan uzorak
doRaytrace(1,320,240,4); // brzi prikaz
doRaytrace(1,320,240,2); // spori prikaz
doRaytrace(1,160,120,2); // četvrtina ekrana
doRaytrace(8); // visoka kvaliteta 320x240 slike uz
// antialiasing s 8 uzoraka

 

Sama funkcija se nalazi u raytracer.h biblioteci pa je potrebno zaviriti u nju radi većih preinaka.
Kôd počinje postavljanjem koordinata kamere te njezinom orijentacijom i postavkama za širinu kuta gledanja.
Zatim su definirana svojstva i boje materijala te pozicije nekoliko kugli. Pokušajte mijenjati ove postavke, kao i pozicije kamere kako biste shvatili i pobliže razumjeli što je to 3D prostor te koliko je on velik. Dodajte još po koju sferu kako biste obogatili scenu. Kreirajte još neki materijal.
Za početak, promijenite jednu varijablu, npr. static const float cameraY = 100.0; kako biste udaljili kameru.
Nakon tako pokrenutog programa, vratite tu varijablu na nulu te promijenite sljedeću, npr. varijablu shadowRegion povećajte za 1 kako biste uočili rasipanje sjene na njezinom rubu.
Funkcija trace() zadužena je za vektorske izračune zraka te se u toj funkciji određuje ide li zraka prema nebu, podu ili je naišla na objekt. Kada smo to odredili, funkcija sample() provjerava scenu i vraća boju piksela zrake prema materijalu na koji je naišla. Nije li zraka naišla na objekt, vratit će vrijednost boje neba ili poda. Ako je naišla na nebo, potrebno ga je malo osjenčati, što se računa unutar if uvjeta if (hit == SKY). Redom se na sličan način računaju ostale vrijednosti za pojedini piksel.
Ako zraka udari u kuglu, trebala bi biti rekurzivna funkcija koja će zraku računati dalje. No kako bi se uštedjelo na RAM-u, a zbog kompatibilnosti kôda sa slabijim mikrokontrolerima poput Arduina, ovdje se ta funkcija poziva ručno 3 puta kroz if uvjet.

if (reflect1 > 0) {
// ...s toga rekurziju radimo ručno
float reflect2 = sample(r,color);
acc += color*reflect1;
if (reflect2 > 0) {
// ...i to 3 nivoa petlje
sample(r,color);
acc += color*(reflect1*reflect2);
}

 

Funkciju smo ostavili ovako kako biste ovaj kôd mogli iskoristiti kao svojevrstan benchmark pokrenete li ga na drugim mikrokontrolerima poput, primjerice, Arduina.

Funkcija zadužena za kretanje od piksela do piksela nazvana je doRaytrace() te se ona i poziva iz glavne Arduino skice.
Pozovete li je uz postavljanje vrijednosti antialiasing na 8 pomoću doRaytrace(8); dobit ćete maksimalnu kvalitetu slike, kao i veće vrijeme računanja tj. renderiranja slike, stoga preporučujemo eksperimentiranje s vrijednostima manjim od 8.
Primijetite da doRaytrace(); funkciju pozivamo 5 puta uz različite vrijednosti. Jednom joj prosljeđujemo 4 varijable, dok joj zadnji puta prosljeđujemo samo jednu varijablu. To možemo zato što su inicijalne vrijednosti varijabli definirane pri kreiranju funkcije u liniji

void doRaytrace(int raysPerPixel = 4, int dw = 320, int dh = 240, int q = 1)

 

te ako varijabla nije proslijeđena funkciji, uzimaju se inicijalno postavljene vrijednosti.

 

 

U serijskoj konzoli biti će ispisano vrijeme potrebno za računanje te funkcije pri njenom pozivanju 5 puta uzastopno, dok na zaslonu Vidi X-a možete vidjeti vrijeme koje je bilo potrebno za računanje pojedine slike.

PRIJTELJI PROJEKTA

bez kojih sve ovo ne bi bilo moguće.

SVA PRAVA PRIDRŽANA - VIDI TO 2020.

Niti jedan dio ovog web site-a ne smije se u bilo kojem obliku ili radi bilo koje namjene reproducirati bez prethodne pismene suglasnosti izdavača, Svi tekstovi objavljeni na www.vidi-x.com pripremljeni su s osobitom pažnjom i kontrolirani na više razina. Redakcija www.vidi-x.com međutim, ni u kojem slučaju ne može odgovarati za moguće štete bilo kakve vrste nastale na osnovu savjeta, tekstova, slika ili drugog redakcijskog ili oglašivačkog materijala objavljenog na www.vidi-x.com ili na drugi način datog od strane zaposlenika ili suradnika izdavača.