Poglavlje 1: Uvod — Šta je real-time renderovanje i zašto postoji
U ovom poglavlju učiš šta zapravo znači prikazati sliku na ekranu u realnom vremenu. Zašto je to teško. Kako smo od prvih piksela na ekranu stigli do fotorealističnih svetova. Šta je game engine, šta je Unreal Engine 5, i zašto bi te sve to uopšte zanimalo.
Zašto ovo poglavlje postoji
Pre nego što uopšte pomeneš reč "Unreal Engine", moraš da razumeš jednu fundamentalnu stvar: sve što vidiš na ekranu — svaki piksel, svaka senka, svaki odsjaj svetlosti na metalnoj površini — neko je morao da izračuna. Računar ne "vidi" svet kao ti. On nema oči, nema intuiciju, nema osećaj za svetlost i boju. Sve što računar zna su brojevi. A posao renderovanja je da te brojeve pretvori u sliku koja tvom mozgu izgleda uverljivo.
Ova knjiga te vodi od potpune nule — od "šta je piksel" — do tačke gde razumeš svaki aspekt kako moderni game engine crta sliku na ekranu, i još važnije, kako da tu sliku učiniš bržom, lepšom i efikasnijom. Ali da bismo stigli tamo, moramo da krenemo od početka.
Šta je renderovanje?
Renderovanje (eng. rendering) je proces pretvaranja podataka u sliku. To je suštinski jednostavna definicija, ali iza nje stoji ogromna količina matematike, inženjerstva i kompromisa.
Zamisli da si arhitekta. Imaš nacrt zgrade — linije na papiru koje predstavljaju zidove, prozore, vrata. Ali klijent hoće da vidi kako će zgrada izgledati kad bude gotova. Hoće fotografiju koja još ne postoji, jer zgrada još nije sagrađena. Ti uzmeš taj nacrt, zamisliš odakle dolazi sunce, kakvi su materijali na fasadi, da li je oblačno ili vedro, i na osnovu svega toga nacrtaš realističnu sliku. To je renderovanje.
U digitalnom svetu, "nacrt" je 3D scena — kolekcija objekata definisanih matematički (o čemu ćemo detaljno u poglavlju 3). "Crtanje" je posao koji obavlja računar — na osnovu pozicije kamere, osvetljenja, materijala i geometrije, izračunava boju svakog piksela na ekranu.
Offline renderovanje vs real-time renderovanje
Postoje dva fundamentalno različita pristupa renderovanju, i razumevanje razlike između njih je ključno za sve što sledi u ovoj knjizi.
Offline renderovanje (ili pre-rendered) je pristup gde vreme nije ograničenje. Kad Pixar pravi film, svaki kadar (frame) može da se renderuje satima, pa čak i danima. Jedan kadar filma "Toy Story" iz 1995. godine renderovao se u proseku 4-13 sati na tadašnjem hardveru. Moderni animirani filmovi mogu da troše i desetine sati po kadru. I to je u redu — film se renderuje jednom, a gleda milion puta. Možeš sebi da priuštiš da izračunaš tačno kako se svaki zrak svetlosti odbija od svake površine, koliko puta hoćeš.
Real-time renderovanje je potpuno druga priča. Ovde moraš da generišeš sliku odmah — dovoljno brzo da korisnik ima iluziju glatkog pokreta. Minimalno 30 puta u sekundi, idealno 60, a za VR čak 90 ili više puta u sekundi. To znači da imaš otprilike 16 milisekundi (za 60 fps) da izračunaš kompletnu sliku — svaki piksel, svaku senku, svaki odsjaj. Šesnaest milisekundi. Za kontekst, ljudski treptaj traje oko 300-400 milisekundi. Dakle, imaš otprilike dvadesetak puta manje vremena nego što ti treba da trepneš.
Ovo ograničenje — vreme — je razlog zašto real-time renderovanje zahteva potpuno drugačiji pristup od offline renderovanja. Ne možeš da izračunaš savršenu fiziku svetlosti. Moraš da varaš. Moraš da pronađeš pametne prečice, aproksimacije koje izgledaju "dovoljno dobro" a koštaju malo računarskih resursa. Čitava istorija real-time grafike je istorija sve pametnijih trikova i prevara.
I upravo to čini ovu oblast fascinantnom. Svaki put kad igraš igru i pomisliš "ovo izgleda neverovatno", to što vidiš nije fizički tačan prikaz svetlosti — to je izuzetno pametan trik koji tvoj mozak ne može da razlikuje od stvarnog.
Piksel — najmanja jedinica slike
Pre nego što bilo šta renderujemo, moramo da razumemo šta zapravo pravimo. Krajnji proizvod renderovanja je rasterska slika — pravougaona mreža tačaka u boji. Svaka ta tačka je piksel (skraćenica od picture element — element slike).
Tvoj monitor je fizička mreža piksela. Ako imaš Full HD monitor (1920×1080), to znači da imaš 1920 kolona i 1080 redova piksela, ukupno 2.073.600 piksela. Svaki od tih piksela može da prikaže jednu boju u datom trenutku. Kad gledaš sliku na ekranu, tvoj mozak spaja te milione obojenih tačaka u koherentnu sliku — prepoznaješ oblike, lica, objekte.
Svaki piksel je tipično opisan sa tri broja: količina crvene, zelene i plave svetlosti (RGB — Red, Green, Blue). Kombinovanjem ove tri osnovne boje u različitim intenzitetima, možeš da dobiješ bilo koju boju koju ljudsko oko može da vidi (ili barem dovoljno blizu). Na primer:
- Crvena = (255, 0, 0) — maksimalno crvene, ništa zelene, ništa plave
- Bela = (255, 255, 255) — maksimalno svega
- Crna = (0, 0, 0) — ništa svetlosti
Posao renderera je da za svaki piksel na ekranu izračuna koja boja treba da bude. Za Full HD rezoluciju pri 60 fps, to znači da moraš da izračunaš boju za preko 124 miliona piksela svake sekunde. A za 4K (3840×2160) pri 60 fps? Preko 497 miliona piksela u sekundi. I svaki od tih piksela potencijalno zahteva kompleksne kalkulacije — osvetljenje, senke, refleksije, transparentnost.
Kad razmišljaš o tome, postaje jasno zašto nam trebaju specijalizovani čipovi za ovaj posao.
Kratka istorija real-time renderovanja
Da bismo razumeli gde smo danas, moramo da znamo odakle smo krenuli. Istorija real-time grafike je priča o konstantnom guranju granica — i o tome kako su pametni ljudi nalazili načine da urade naizgled nemoguće sa ograničenim resursima.
Era pre GPU-a: Software rendering (1960-ih do 1990-ih)
U najranijim danima kompjuterske grafike, sve se računalo na CPU-u (Central Processing Unit — centralni procesor). CPU je "mozak" računara — opštenamenski čip dizajniran da radi raznorazne zadatke. Nije specijalizovan za grafiku, ali je jedini čip koji je postojao.
1960-e: Wireframe i vektorska grafika
Prve kompjuterske grafike uopšte nisu bile pikseli u današnjem smislu. Bile su to linije na vektorskim ekranima — ekranima koji su elektronskim snopom direktno crtali linije, slično osciloskopu. Ivan Sutherland je 1963. godine kreirao Sketchpad, često smatran prvim interaktivnim grafičkim programom. Korisnik je mogao da crta geometrijske oblike i manipuliše njima u realnom vremenu. Bio je to revolucionaran koncept — ideja da računar može da prikazuje vizuelne informacije s kojima čovek može da interaguje.
Iste decenije, Sutherland je radio i na prvomHead-Mounted Display-u (1968), preteči modernog VR-a. Nazvan je "Sword of Damocles" jer je bio toliko težak da je morao da visi sa plafona. Ali princip je bio isti kao kod danas — prikazati sliku koja se menja u zavisnosti od pozicije glave korisnika, u realnom vremenu.
1970-e: Rasterizacija i prvi 3D
Tokom sedamdesetih, grafika prelazi sa vektorskih ekrana na rasterske — ekrane sa fiksnom mrežom piksela kakve koristimo i danas. Ovo je fundamentalna promena jer sada moraš da "popuniš" trouglove bojom, ne samo da nacrtaš njihove ivice.
Razvijaju se ključni algoritmi koji se koriste i dan-danas:
- Z-buffer (depth buffer) algoritam, koji rešava problem koji objekat je ispred kog. Edwin Catmull (kasnije suosnivač Pixara) je opisao ovaj koncept 1974. Ideja je genijalno prosta: za svaki piksel, osim boje, čuvaš i udaljenost od kamere. Kad crtaš novi piksel, proveriš da li je bliži kameri od onog koji je već tu. Ako jeste, prepiši ga. Ako nije, preskoči.
- Gouraud shading (1971) — tehnika glatkog senčenja gde se boja interpolira između temena trougla, dajući iluziju zaobljene površine umesto fasetiranog izgleda.
- Phong shading (1975) — poboljšanje koje interpolira normale umesto boja, dajući još uverljivije osvetljenje, posebno za spekularne odsjaje.
U ovoj eri, sve ovo se računa na CPU-u, i to veoma sporo. "Real-time" 3D grafika u modernom smislu praktično ne postoji za prosečne korisnike. Ali temelji su postavljeni.
1980-e: Arkadne mašine i kućni računari
Osamdesete donose prvu popularizaciju real-time grafike, pre svega kroz arkadne igre. Igre poput Battlezone (1980) prikazuju rudimentarnu 3D wireframe grafiku u realnom vremenu. Elite (1984) na BBC Micro-u prikazuje čitav otvoreni svet u wireframe 3D — neverovatno dostignuće za mašinu sa manje računarske snage nego što ima moderan digitron.
Ali prava 3D grafika sa ispunjenim poligonima (a ne samo žicama) je i dalje izuzetno skupa. Većina igara koristi 2D sprite grafiku — unapred nacrtane sličice koje se prikazuju na ekranu. Čak i ove 2D igre zahtevaju specijalizovane čipove za prikaz sprite-ova, pozadina i skrolovanje — rani preteče GPU-a, ali još uvek veoma daleko od modernog 3D renderovanja.
Rani 1990-e: Softverski rendereri i prva 3D revolucija
Devedesete su dekada koja menja sve. Na početku decenije, imaš igre poput Wolfenstein 3D (1992) i Doom (1993) od id Software-a — Johna Carmacka i Johna Romera. Ove igre prikazuju 3D svet u realnom vremenu na običnom PC-ju, potpuno softverski — bez ikakve hardverske akceleracije za grafiku.
Kako? Trikovima. Wolfenstein 3D koristi raycasting — tehniku gde za svaku vertikalnu kolonu piksela na ekranu šalješ jedan zrak od kamere i gledaš šta pogađa. Svi zidovi su iste visine, podovi i plafoni su ravni, a svet je zapravo 2D mapa. Ali rezultat izgleda 3D i pokreće se glatko na 386-ici.
Doom ide korak dalje — ima različite visine, stepenišne strukture, osvetljenje koje varira — ali je suštinski i dalje 2.5D. Prava 3D sloboda (mogućnost gledanja gore-dole) stiže sa Quake-om (1996), koji je prvi mainstream FPS sa potpuno 3D svetom i softverskim rendererom koji radi triangulaciju svakog poligona.
Softversko renderovanje u Quake-u je bio podvig. Carmack je koristio svaku optimizaciju poznatu čovečanstvu — fixed-point aritmetiku umesto floating-point (jer su floating-point operacije bile spore na tadašnjim CPU-ovima), BSP stabla za efikasno određivanje vidljivosti, PVS (Potentially Visible Set) za izbegavanje crtanja nevidljivih delova sveta, surface caching da ne računa osvetljenje ponovo za površine koje se nisu promenile. Svaki takt procesora je bio dragocen.
Ali bilo je jasno da CPU ne može da drži korak sa sve većim zahtevima. Trebao je specijalizovan čip.
Rođenje GPU-a (sredina 1990-ih)
1996-1999: 3dfx, NVIDIA i prva generacija grafičkih akceleratora
Grafički akceleratori su postojali i pre ovog perioda — Silicon Graphics (SGI) je pravio workstation mašine sa hardverskom akceleracijom za profesionalnu upotrebu (filmska industrija, CAD, vojska). Ali te mašine su koštale desetine hiljada dolara.
Pravu revoluciju donosi 3dfx sa svojim Voodoo čipom (1996). Voodoo je bio add-in kartica za PC koja je mogla da radi jednu stvar — rasterizaciju trouglova sa texture mappingom — ali je to radila mnogo brže nego što je CPU mogao. Kada bi Quake koristio Voodoo karticu umesto softverskog renderera, razlika je bila dramatična — više frejmova u sekundi, bilinearno filtriranje tekstura (glatke teksture umesto pikseliziranih), i sve to na većoj rezoluciji.
3dfx je uveo Glide API — programski interfejs kroz koji su igre komunicirale sa Voodoo hardverom. Paralelno, OpenGL (nastao iz SGI-jevog IRIS GL-a) je postajao standard za 3D grafiku koji nije vezan za jednog proizvođača.
- godine, NVIDIA lansira GeForce 256, koji marketinski proglašavaju prvim "GPU-om" (Graphics Processing Unit). Ključna inovacija je bila hardware transform and lighting (T&L) — prebacivanje transformacija geometrije i proračuna osvetljenja sa CPU-a na grafički čip. Pre toga, čak i sa 3D akceleratorima, CPU je i dalje morao da uradi svu matematiku sa temenima (vertices) — pozicioniranje u prostoru, proračun osvetljenja — i tek onda prosledi pripremljene trouglove grafičkom čipu na rasterizaciju. GeForce 256 je preuzeo i taj posao.
Ovo je bio ključan momenat. GPU je počeo da preuzima sve više i više posla od CPU-a, i taj trend se nastavlja do danas.
Paralelno: DirectX i Microsoft
Microsoft je 1995. godine lansirao DirectX — kolekciju API-ja za multimediju na Windows-u, uključujući Direct3D za 3D grafiku. Rani DirectX (verzije 1-6) su bili ograničeni i nepopularni u poređenju sa OpenGL-om i Glide-om, ali Microsoft je uporno gurao napred. DirectX 7 (1999) je dodao hardware T&L podršku, a DirectX 8 (2000) je doneo revoluciju — programabilne shadere.
Era programabilnih shadera (2001-2006)
Ovo je period koji je fundamentalno promenio real-time grafiku.
Do ovog momenta, GPU je bio fixed-function pipeline — imao je unapred definisane operacije koje može da uradi (nanese teksturu, izračuna osvetljenje po Gouraud ili Phong modelu, uradi alfa blending), i ti si mogao samo da biraš koje od tih operacija da uključiš i sa kojim parametrima. Ako si hteo neki efekat koji nije bio predviđen hardverom — nisi mogao da ga dobiješ.
DirectX 8 (2000) i GeForce 3 (2001) uvode programabilne vertex i pixel shadere — male programe koje programer piše i koji se izvršavaju na GPU-u za svaki vertex ili piksel. Umesto fiksnih operacija, sada možeš da napišeš proizvoljnu matematiku. Ovo je kao razlika između kalkulatora koji ima samo +, -, ×, ÷ i programabilnog računara gde možeš da napišeš bilo koji program.
Rane verzije shadera su bile veoma ograničene — mali broj instrukcija, ograničen pristup teksturama, nema petlji, nema grananja. Ali sa svakom generacijom, mogućnosti su rasle:
- Shader Model 1.0 (2001) — basic vertex i pixel shaderi, veoma ograničeni
- Shader Model 2.0 (2003, DirectX 9.0) — duži shaderi, više instrukcija, bolja preciznost
- Shader Model 3.0 (2004, DirectX 9.0c) — dinamičko grananje, veći broj instrukcija, vertex texture fetch
- Shader Model 4.0 (2006, DirectX 10) — Unified Shader Architecture — vertex, pixel i novi geometry shaderi dele isti hardver
- Shader Model 5.0 (2009, DirectX 11) — tessellation shaderi, compute shaderi
Unified Shader Architecture (od Shader Model 4.0) je bio značajan korak. Pre toga, GPU je imao odvojene hardverske jedinice za vertex shadere i pixel shadere. Problem je bio što u nekim scenama imaš puno geometrije ali proste materijale (vertex shaderi su zauzeti, pixel shaderi čekaju), a u drugim malo geometrije ali kompleksne materijale (obrnuto). Sa unified arhitekturom, iste hardverske jedinice mogu da izvršavaju bilo koji tip shadera, pa se resursi dinamički raspodeljuju prema potrebi.
Moderna era (2013-danas)
2013-2016: Low-level API-ji i eksplicitna kontrola
DirectX 11 i OpenGL su bili "high-level" API-ji — driver je radio puno posla iza scene (upravljanje memorijom, sinhronizacija, optimizacija). To je bilo zgodno za programere ali je značilo da driver ponekad ne može da optimizuje onoliko koliko bi bilo moguće. Uz to, CPU overhead za svaki draw call (zahtev GPU-u da nacrta nešto) je bio značajan, što je ograničavalo koliko objekata možeš da nacrtaš.
Mantle (2013, AMD), a zatim Vulkan (2016, Khronos Group) i DirectX 12 (2015, Microsoft) donose "low-level" pristup — programer ima eksplicitniju kontrolu nad GPU-om, ali i veću odgovornost. Manje driver magije, više manuelnog upravljanja. Ovo omogućava dramatično smanjenje CPU overhead-a za draw call-ove i efikasnije korišćenje hardvera.
Apple uvodi Metal (2014) kao svoj low-level API za iOS i macOS.
2018: Real-time ray tracing
NVIDIA-ina Turing arhitektura (GeForce RTX 2000 serija, 2018) donosi RT cores — specijalizovane hardverske jedinice za ray tracing operacije, pre svega ray-BVH intersection testove (o čemu detaljno u poglavlju 14). Microsoft uvodi DirectX Raytracing (DXR) kao ekstenziju DirectX 12.
Ovo ne zamenjuje rasterizaciju — umesto toga, moderne igre koriste hibridni pristup: osnovna slika se i dalje renderuje rasterizacijom (jer je to i dalje brže za većinu zadataka), a ray tracing se koristi selektivno za efekte gde daje dramatično bolje rezultate — refleksije, senke, globalna iluminacija.
2020-e: Virtualna geometrija i dinamička globalna iluminacija
Unreal Engine 5 (najava 2020, puno lansiranje 2022) donosi dva revolucionarna sistema:
- Nanite — virtualizovana geometrija koja omogućava renderovanje scena sa milijardama trouglova u realnom vremenu
- Lumen — potpuno dinamička globalna iluminacija i refleksije u realnom vremenu, bez potrebe za baking
O oba sistema detaljno u kasnijim poglavljima (30 i 25), ali njihova pojava predstavlja značajan skok u tome šta je moguće u real-time grafici.
Gde smo danas?
Danas se nalazimo u eri gde se granica između offline i real-time renderovanja sve više zamagljuje. Tehnike koje su pre 10 godina bile isključivo domen filmske industrije (path tracing, subsurface scattering, volumetrička oblačnost) sada su dostupne u realnom vremenu, bar u aproksimiranom obliku. Path tracing u realnom vremenu — tehnika gde se za svaki piksel simulira fizički tačno ponašanje svetlosti — postaje moguć zahvaljujući kombinaciji RT hardvera i AI denoising-a (NVIDIA DLSS, AMD FSR).
Istovremeno, pritisak raste sa svih strana: rezolucije rastu (4K postaje standard, 8K kuca na vrata), HDR zahteva veći dinamički opseg boja, VR zahteva ekstremno visoke frame rate-ove i niske latencije, a očekivanja igrača i korisnika u pogledu vizuelnog kvaliteta rastu brže nego što hardver može da ih ispuni.
I tu nastupa optimizacija — veština koja je tema poslednjeg i najvećeg dela ove knjige.
Šta je frame rate i zašto je bitan
Pominjali smo frame rate (broj frejmova u sekundi, fps), ali hajde da razjasnimo koncept detaljnije jer je fundamentalan za sve što radimo.
Animacija — bilo filmska, bilo kompjuterska — je iluzija pokreta nastala brzim prikazivanjem nepokretnih slika. Svaka ta slika je jedan frame (kadar). Ako prikazuješ 24 kadra u sekundi (standard za film), mozak "vidi" glatki pokret umesto 24 odvojene slike.
U igrama i interaktivnim aplikacijama, svaki frame se generiše u realnom vremenu. To znači da se čitav proces renderovanja — od obrade geometrije do finalnog piksela — mora završiti dovoljno brzo da novi frame bude spreman za prikazivanje.
Frame time vs frame rate
Ljudi obično govore o frame rate-u (fps), ali za razumevanje performansi je korisnije razmišljati o frame time — koliko vremena traje renderovanje jednog kadra.
| Frame rate | Frame time |
|---|---|
| 30 fps | 33.3 ms |
| 60 fps | 16.7 ms |
| 90 fps (VR) | 11.1 ms |
| 120 fps | 8.3 ms |
| 144 fps | 6.9 ms |
Zašto je frame time korisniji? Zato što je linearan. Razlika između 30 fps i 60 fps je 16.7 ms (ogromna). Razlika između 120 fps i 150 fps je samo 1.4 ms (mala). Kad optimizuješ, smanjuješ frame time — i efekat tog smanjenja je mnogo veći pri nižim frame rate-ovima.
Na primer, ako uspeš da uštedeš 5 ms na frame time-u:
- Sa 33.3 ms (30 fps) ideš na 28.3 ms (35 fps) — osetno poboljšanje
- Sa 6.9 ms (144 fps) ideš na 1.9 ms (526 fps) — razlika koju niko neće primetiti
Ovo je važna lekcija koja će se provlačiti kroz cele optimizacione delove knjige: optimizacija je najvrednija tamo gde je najpotrebnija, i efekti su nelinearni.
VSync, screen tearing i frame pacing
Tvoj monitor osvežava sliku fiksnim tempom — obično 60 Hz (60 puta u sekundi), mada moderni monitori idu do 144 Hz, 240 Hz, pa čak i 360 Hz. Kad GPU završi renderovanje frejma, on ga šalje monitoru. Ali šta se dešava kad GPU i monitor nisu sinhronizovani?
Screen tearing — ako GPU pošalje novi frejm dok monitor još prikazuje prethodni, dobijaš vidljivu horizontalnu liniju gde se dva frejma spajaju. Gornji deo ekrana prikazuje stari frejm, donji deo novi — ili obrnuto. Rezultat je vizuelno neprijatan "cepajući" efekat.
VSync (Vertical Synchronization) rešava tearing tako što primorava GPU da čeka da monitor završi osvežavanje pre nego što pošalje novi frejm. Ali ovo uvodi problem: ako GPU nije stigao da završi frejm na vreme, mora da čeka ceo sledeći ciklus monitora. Na 60 Hz monitoru, to znači da ako frejm traje 17 ms umesto 16.7 ms, ne dobijaš 59 fps nego 30 fps — jer mora da čeka dvostruko. Ovo je poznat problem "VSync stutter".
Moderna rešenja poput G-Sync (NVIDIA) i FreeSync (AMD) koriste adaptivne refresh rate monitore — umesto da monitor ima fiksnu frekvenciju osvežavanja, on se prilagođava GPU-u i osvežava ekran kad god GPU ima spreman frejm. Ovo eliminiše i tearing i stuttering.
Frame pacing je još jedan bitan koncept — čak i ako je prosečan fps visok, ako neki frejmovi traju mnogo duže od drugih, rezultat je vizuelno "štucanje" (stutter). Konzistentan frame time je jednako bitan kao visok frame rate. Bolje je imati stabilnih 30 fps nego 60 fps koji povremeno padne na 20.
Šta je game engine?
Sad kad razumeš osnove renderovanja, hajde da pričamo o alatu koji sve to objedinjuje.
Game engine je, u najjednostavnijem smislu, softverski okvir (framework) za pravljenje interaktivnih aplikacija — pre svega igara, ali i arhitektonskih vizualizacija, filmskih produkcija, simulacija, VR/AR iskustava i mnogo toga drugog.
Zašto engine uopšte postoji?
Zamisli da praviš igru. Trebaš:
- Da renderuješ 3D grafiku u realnom vremenu
- Da učitavaš i upravljaš resursima (modeli, teksture, zvuci)
- Da obrađuješ input od igrača (tastatura, miš, gamepad)
- Da simuliraš fiziku (gravitacija, kolizije, ragdoll)
- Da pušaš zvuk i muziku, sa prostornim pozicioniranjem
- Da upravljaš veštačkom inteligencijom neprijatelja
- Da šalješ i primaš podatke preko mreže (multiplayer)
- Da sve to radi glatko, bez zastoja, na različitom hardveru
Svaka od ovih stavki je sama po sebi ozbiljan inženjerski izazov. Pravljenje svega od nule za svaku igru bi bilo kao da za svaku novu kuću praviš i ciglanu, i pilanu, i čeličanu. Umesto toga, koristiš gotove cigle i grede — a game engine je fabrika koja ti ih isporučuje.
Komponente tipičnog game engine-a
Moderni game engine obično sadrži sledeće sisteme:
Rendering engine — srce vizuelnog prikaza. Upravlja čitavim procesom pretvaranja 3D scene u 2D sliku na ekranu. Ovo uključuje upravljanje shaderima, osvetljenjem, senkama, post-processing efektima, i sve ostalo što se tiče "crtanja". Ovo je daleko najveći i najkompleksniji deo engine-a, i ujedno fokus ove knjige.
Scene graph / World management — sistem koji organizuje sve objekte u sceni — ko je gde, ko je čiji "dete" (parent-child hijerarhija), šta je vidljivo a šta ne. U velikim svetovima, ovo uključuje i streaming — učitavanje i otpuštanje delova sveta po potrebi.
Physics engine — simulacija fizike. Većina engine-a koristi postojeće fizičke biblioteke: Unreal Engine koristi modifikovanu verziju Chaos fizičkog sistema (ranije PhysX). Physics engine obavlja detekciju kolizija (da li se dva objekta dodiruju), odgovor na koliziju (šta se dešava kad se dodirnu — odskakanje, klizanje), simulaciju krutih tela (rigid body), mekih tela (soft body), ragdoll fiziku, simulaciju tkanine, itd.
Audio engine — reprodukcija zvuka sa prostornim pozicioniranjem (3D audio), reverberacijom, okluzijom (zvuk je tiši iza zida), atenuacijom (zvuk je tiši što si dalje). Unreal Engine 5 koristi MetaSounds sistem.
Input system — obrada korisničkog unosa sa različitih uređaja — tastatura, miš, gamepad, touch screen, VR kontroleri. Mapiranje fizičkih dugmadi na apstraktne akcije u igri.
Animation system — skeletalna animacija (kosti i zglobovi), blending između animacija, inverse kinematics (IK), proceduralna animacija. Unreal Engine koristi Control Rig i Animation Blueprint sisteme.
AI system — navigacija (pathfinding), stabla ponašanja (behavior trees), percepcija (AI "vidi" i "čuje" stvari u svetu). Unreal Engine ima AI Controller, Behavior Tree, i Environment Query System (EQS).
Networking — multiplayer podrška, replikacija stanja objekata, predikcija kretanja, kompenzacija latencije. Unreal Engine ima sopstveni networking layer sa replikacijom, RPC pozivima, i relevancy sistemom.
UI framework — sistem za pravljenje korisničkog interfejsa — meniji, HUD, inventar. Unreal Engine koristi UMG (Unreal Motion Graphics) sa Slate widget frameworkom ispod.
Asset pipeline — import, konverzija i optimizacija resursa — od 3D modela i tekstura do zvukova i animacija. Ovo uključuje i kompresiju, generisanje LOD-ova (Level of Detail — različite verzije modela za različite udaljenosti), i druge transformacije.
Scripting / Gameplay framework — sistem koji programerima i dizajnerima omogućava da definišu logiku igre. Unreal Engine nudi C++ za programere i Blueprints — vizuelni scripting sistem za dizajnere.
Editor — grafički alat za kreiranje i uređivanje sadržaja igre. Moderni editori su kompleksni alati koji integrišu sve gore navedene sisteme u jedinstven radni prostor.
Pravljenje sopstvenog vs korišćenje gotovog engine-a
Postoji večita debata: da li koristiti gotov engine (Unreal, Unity, Godot) ili napraviti svoj?
Argumenti za sopstveni engine:
- Potpuna kontrola nad svakim aspektom
- Može biti optimizovan tačno za tvoj tip igre
- Nema licencnih troškova ili ograničenja
- Dublje razumevanje tehnologije
Argumenti za gotov engine:
- Hiljade čovek-godina rada, odmah dostupne
- Testirano na stotinama komercijalnih proizvoda
- Velika zajednica, dokumentacija, tutoriali
- Konstantno se unapređuje sa novim tehnologijama
U praksi, velika većina studija danas koristi gotove engine-e. Samo najveći AAA studiji (i to ne svi) i dalje održavaju sopstvene — CD Projekt RED (REDengine), id Software (id Tech), Naughty Dog. Čak i oni sve više razmatraju prelazak na Unreal Engine jer je trošak održavanja sopstvenog engine-a ogroman.
Za nekoga ko uči, gotov engine je jedini razuman izbor. Ali — i ovo je ključno — razumevanje šta se dešava ispod haube je jednako bitno kao i znanje kako koristiti alat. Vozač koji razume kako motor radi može bolje da vozi, efikasnije troši gorivo, i brže dijagnostikuje problem kad se nešto pokvari. Isto važi i za game engine.
Upravo zato ova knjiga počinje od matematike i osnova renderovanja, a ne od "kako otvoriti Unreal Editor".
Unreal Engine — ko, šta, zašto
Kratka istorija Unreal Engine-a
Unreal Engine je game engine koji razvija Epic Games, američka kompanija osnovana 1991. godine od strane Tima Sweeney-ja. Sweeney je počeo da radi na engine-u sredinom 1990-ih, a prva igra koja ga je koristila — Unreal — izašla je 1998. godine.
Od tada, engine je prošao kroz nekoliko generacija:
Unreal Engine 1 (1998) — korišćen u originalnom Unreal-u i Unreal Tournament-u. Za svoje vreme, imao je impresivan softverski renderer, podršku za colored lighting, i rudimentarni level editor (UnrealEd). Bio je jedan od prvih engine-a koji je nudio licenciranje trećim stranama.
Unreal Engine 2 (2002) — korišćen u Unreal Tournament 2003/2004, Lineage II, Splinter Cell i drugim. Donosi poboljšan renderer sa particle sistemima, skeletal animacijom, i boljim alatima.
Unreal Engine 3 (2006) — ovo je generacija koja je Unreal Engine učinila dominantnim. Korišćen u ogromnom broju igara: Gears of War, Mass Effect, Batman: Arkham serijal, Bioshock Infinite, Borderlands, i stotine drugih. UE3 je uveo Kismet (vizuelni scripting) i Material Editor — koncept koji se održao do danas. Deferred rendering, dinamičko osvetljenje, napredni post-processing — sve je to postalo standard.
Unreal Engine 4 (2014) — ogroman skok u dostupnosti. Epic je učinio UE4 besplatnim za korišćenje, sa 5% royalty na prihode iznad praga. Ovo je otvorilo engine širokoj publici — indie developerima, studentima, hobi entuzijastima. UE4 donosi Blueprints (naslednik Kismeta, ali mnogo moćniji), PBR rendering pipeline, poboljšane alate, i mnogo više. Korišćen u Fortnite, Final Fantasy VII Remake, Star Wars Jedi serijalu, Hellblade, i bezbroj drugih projekata.
Unreal Engine 5 (2022) — trenutna generacija i fokus ove knjige. Donosi revolucionarne sisteme:
- Nanite — virtualizovana mikro-poligon geometrija
- Lumen — potpuno dinamička globalna iluminacija i refleksije
- Virtual Shadow Maps — senke visokog kvaliteta za Nanite geometriju
- World Partition — sistem za upravljanje velikim otvorenim svetovima
- MetaSounds — proceduralni audio sistem
- Chaos fizički sistem (zamena za PhysX)
- Control Rig — proceduralna animacija
- TSR (Temporal Super Resolution) — upscaling tehnika
Zašto je UE5 bitan?
Unreal Engine 5 je, u trenutku pisanja ove knjige, jedan od dva dominantna komercijalna game engine-a (drugi je Unity). Koristi se ne samo za igre, već i za:
- Film i televiziju — Disney's The Mandalorian koristi Unreal Engine za real-time pozadine snimane StageCraft LED volumima. Isto tako Westworld, The Batman, i mnogi drugi.
- Arhitektonsku vizualizaciju — interaktivni walk-through-ovi zgrada pre nego što budu izgrađene, sa fotorealističnim kvalitetom.
- Automobilsku industriju — konfiguratori vozila, virtualni showroom-ovi.
- Simulacije i trening — vojni simulatori, medicinski trening, industrijski digital twin.
- Live events i broadcast — virtualni setovi za TV emisije, sportske prenose.
UE5 je bitan zato što predstavlja vrh onoga što je trenutno moguće u real-time renderovanju. Razumevanje kako on radi — ne samo kako ga koristiti, već zašto radi tako kako radi — daje ti fundamentalno znanje koje je prenosivo na bilo koji drugi engine ili grafički sistem.
Licenciranje
Unreal Engine 5 je besplatan za korišćenje. Epic naplaćuje 5% royalty na prihode koji prelaze milion dolara po proizvodu. Za filmsku produkciju, arhviz, i druge ne-igračke namene, nema royalty-ja. Ovo čini UE5 izuzetno pristupačnim za učenje i eksperimentisanje.
Pored toga, čitav source code Unreal Engine-a je dostupan na GitHub-u (uz registraciju Epic naloga). Ovo je ogromna prednost za razumevanje engine-a — kad god se zapitaš "ali kako to zapravo radi?", možeš da pogledaš izvorni kod.
Kako je organizovan rendering u modernom engine-u
Hajde da damo visok pregled kako zapravo izgleda proces renderovanja jednog frejma u modernom engine-u poput UE5. Ovo je pojednostavljeno — svaki od ovih koraka će biti detaljno objašnjen u kasnijim poglavljima — ali je korisno imati mentalnu mapu od samog početka.
1. Game thread: Priprema scene
Pre nego što rendering uopšte počne, engine mora da zna šta da renderuje. Game thread (nit koja izvršava gameplay logiku) ažurira stanje sveta:
- Gde se igrač nalazi?
- Koji objekti su se pomerili?
- Koja svetla su upaljena?
- Koje animacije se reprodukuju?
- Koji particle sistemi su aktivni?
Rezultat je ažurirano stanje scene — lista svih objekata, njihovih pozicija, materijala, i drugih relevantnih podataka.
2. Render thread: Priprema za GPU
Render thread prima ažurirano stanje scene od game thread-a i priprema ga za GPU:
- Culling — određivanje koji objekti su vidljivi kameri (frustum culling) i koji su zaklonjeni drugim objektima (occlusion culling). Nema smisla slati GPU-u objekte koje kamera ne vidi.
- Sortiranje — objekti se sortiraju po materijalima, rastojanju od kamere, i drugim kriterijumima radi efikasnosti.
- Priprema draw call-ova — za svaki vidljivi objekat, render thread priprema komande za GPU: "nacrtaj ovaj mesh, sa ovim materijalom, na ovoj poziciji".
3. GPU: Renderovanje
GPU prima komande i izvršava rendering pipeline (detaljno u poglavlju 7):
- Vertex processing — transformacija geometrije iz 3D prostora na 2D ekran
- Rasterizacija — pretvaranje trouglova u fragmente (potencijalne piksele)
- Fragment/Pixel processing — izračunavanje boje svakog fragmenta na osnovu materijala, osvetljenja, senki
- Output — finalni pikseli se upisuju u framebuffer
4. Post-processing
Nakon što se osnovna slika renderuje, primenjuju se post-processing efekti:
- Bloom (sjaj jakih svetlosnih izvora)
- Tone mapping (prevođenje HDR vrednosti u prikazive boje)
- Anti-aliasing (uklanjanje nazubljenosti ivica)
- Motion blur, depth of field, i drugi efekti
5. Prikaz na ekranu
Finalna slika se šalje monitoru za prikazivanje, i ceo proces počinje ispočetka za sledeći frejm.
Čitav ovaj proces — od game logic-a do piksela na ekranu — mora da se završi u roku od 16.7 ms za 60 fps. I ne jednom, nego svakog frejma, bez prestanka, dok god aplikacija radi.
CPU vs GPU — fundamentalna razlika
Ovo je toliko bitna tema da joj je posvećeno čitavo poglavlje kasnije (poglavlje 8), ali uvodni pregled je neophodan odmah.
CPU (Central Processing Unit) je dizajniran da bude dobar u svemu. Ima malo jezgara (4-16 u tipičnom desktop procesoru), ali svako jezgro je veoma moćno — može da izvršava kompleksne, razgranate instrukcije sa mnogo uslovnih grananja. CPU je kao visokokvalifikovani stručnjak — može da uradi bilo šta, ali radi jednu stvar u jednom trenutku (po jezgru).
GPU (Graphics Processing Unit) je dizajniran za jednu specifičnu stvar: masivno paralelnu obradu. Ima hiljade malih jezgara (NVIDIA RTX 4090 ima 16384 CUDA jezgra), gde svako jezgro pojedinačno nije naročito moćno, ali svi rade istovremeno. GPU je kao vojska radnika na pokretnoj traci — svaki radi jednostavan posao, ali ih ima hiljade i rade paralelno.
Renderovanje je inherentno paralelizabilan problem. Kad računaš boju piksela na ekranu, boja piksela (500, 300) uglavnom ne zavisi od boje piksela (100, 200). Možeš da ih računaš istovremeno. A kad imaš 2 miliona piksela za obraditi, paralelizam je jedini način da se to završi na vreme.
Ova fundamentalna razlika — CPU radi malo kompleksnih zadataka sekvencijalno, GPU radi mnogo jednostavnih zadataka paralelno — je ključ za razumevanje čitavog polja real-time renderovanja i optimizacije.
Kad nešto radi sporo, prvo pitanje je uvek: "Da li je problem na CPU-u ili na GPU-u?" Odgovor na to pitanje određuje potpuno različit pristup optimizaciji, kao što ćemo detaljno videti u delu 6.
Šta ćeš naučiti u ovoj knjizi
Hajde da eksplicitno navedemo šta ćeš znati kad završiš ovu knjigu:
Posle dela 1 (Osnove 3D grafike):
- Razumećeš matematiku iza 3D renderovanja — vektore, matrice, transformacije
- Znavaćeš šta je mesh, kako je organizovan, zašto se koriste trouglovi
- Razumećeš UV mapping i teksturiranje
- Znavaćeš kroz koje prostore prolazi geometrija od 3D modela do piksela na ekranu
- Imaćeš pregled celog render pipeline-a
- Razumećeš zašto GPU radi kako radi
Posle dela 2 (Rendering teorija):
- Razumećeš kako rasterizacija zapravo radi — ne na visokom nivou, nego detaljno
- Znavaćeš teoriju osvetljenja i PBR renderovanja
- Razumećeš globalnu iluminaciju, senke, ray tracing
- Znavaćeš šta je post-processing i kako svaki efekat radi
- Imaćeš osnove color science-a
Posle dela 3 (Materijali i shaderi):
- Razumećeš šta je shader i kako radi na GPU-u
- Znavaćeš različite material modele i kad se koji koristi
- Razumećeš teksturne tehnike (normal mapping, parallax, itd.)
- Moći ćeš da proceniš "cenu" materijala i optimizuješ ga
Posle dela 4 (Svetla u praksi):
- Razumećeš sve tipove svetla i njihove karakteristike
- Znavaćeš razliku između statičkog i dinamičkog osvetljenja
- Razumećeš kako Lumen radi i gde su mu granice
- Moći ćeš da osmisliš lighting workflow za različite tipove scena
Posle dela 5 (UE5 specifično):
- Razumećeš UE5 rendering arhitekturu — deferred shading, GBuffer, render passes
- Znavaćeš kako Nanite, VSM, TSR, Virtual Textures rade ispod haube
- Razumećeš World Partition i kako UE5 upravlja velikim svetovima
- Znavaćeš asset pipeline i packaging proces
Posle dela 6 (Optimizacija):
- Imaćeš sistematičan pristup optimizaciji — profiling-first mentalitet
- Znavaćeš sve relevantne profiling alate i kad se koji koristi
- Razumećeš sve glavne kategorije performance problema i kako ih rešiti
- Moći ćeš da uzmeš kompleksnu scenu i sistematično je optimizuješ
- Kroz studije slučaja, videćeš primenu svega naučenog na realističnim scenarijima
Kako koristiti ovu knjigu
Ova knjiga je dizajnirana da se čita linearno — od početka do kraja. Svako poglavlje gradi na prethodnim. Ako preskočiš poglavlje o koordinatnim prostorima, nećeš razumeti rendering pipeline. Ako ne razumeš rendering pipeline, nećeš shvatiti zašto je Nanite revolucionaran. Ako ne shvatiš Nanite, nećeš moći da ga pravilno optimizuješ.
Ipak, ako već imaš znanje iz nekih oblasti, možeš da preskočiš odgovarajuća poglavlja. Na početku svakog poglavlja je navedeno šta se od čitaoca očekuje da već zna.
Ova knjiga je čisto konceptualna i teorijska. Nema "korak po korak" uputstava tipa "klikni ovde, zatim ovde". Cilj je da razumeš zašto stvari rade, ne samo kako da ih koristiš. Kad razumeš zašto, "kako" postaje trivijalno — samo pročitaš dokumentaciju.
Analogija: ova knjiga te uči da razumeš auto — motor, menjač, aerodinamiku, fiziku vožnje. Neće te naučiti gde je dugme za klima uređaj u specifičnom modelu auta. Ali kad razumeš kako auto funkcioniše, naći ćeš to dugme za tri sekunde.
Terminologija i jezik
Ova knjiga je napisana na srpskom jeziku, ali koristi englesku tehničku terminologiju gde je to standard u industriji. Razlog je praktičan: ako naučiš da se "osvetljenje" kaže samo "osvetljenje", nećeš moći da pretražuješ dokumentaciju, forume, ili resurse koji gotovo isključivo koriste termin "lighting".
Pristup je sledeći:
- Kad se termin prvi put pojavi, daje se i engleski i srpski ekvivalent (gde postoji razuman prevod)
- Nakon toga, koristi se termin koji je uobičajeniji u praksi (obično engleski za tehničke termine)
- Srpski se koristi za opšte koncepte i objašnjenja
Na primer: "Renderovanje (rendering) je proces..." — posle ovoga, koristimo "renderovanje" jer je termin odomaćen u srpskom jeziku. Ali "vertex shader" ostaje "vertex shader" jer prevod "shader za temena" niko ne koristi.
Rezime ključnih pojmova
| Pojam | Značenje |
|---|---|
| Renderovanje | Proces pretvaranja podataka (3D scene) u sliku (2D piksele) |
| Real-time renderovanje | Renderovanje dovoljno brzo za interaktivan prikaz (tipično 30+ fps) |
| Offline renderovanje | Renderovanje bez vremenskog ograničenja (filmovi, slike) |
| Frame | Jedan kadar — jedna kompletna slika |
| Frame rate (fps) | Broj frejmova generisanih u sekundi |
| Frame time | Vreme potrebno za generisanje jednog frejma (u milisekundama) |
| Piksel | Najmanja jedinica rasterske slike — jedna tačka u boji |
| CPU | Opštenamenski procesor — mali broj moćnih jezgara |
| GPU | Grafički procesor — ogroman broj jednostavnih jezgara za paralelnu obradu |
| Shader | Program koji se izvršava na GPU-u za obradu grafičkih podataka |
| Game engine | Softverski okvir za pravljenje interaktivnih aplikacija |
| VSync | Sinhronizacija GPU izlaza sa refresh rate-om monitora |
| Screen tearing | Vizuelni artefakt kad su GPU i monitor desinhronizovani |
| Draw call | Komanda kojom CPU govori GPU-u da nacrta nešto |
| Rasterizacija | Proces pretvaranja vektorske geometrije u piksele |
| API (Graphics API) | Interfejs za komunikaciju sa GPU-om (DirectX, Vulkan, OpenGL, Metal) |
U sledećem poglavlju krećemo sa matematičkim osnovama — koordinatni sistemi, vektori, matrice i transformacije. Ako misliš "ja mrzim matematiku" — ne brini. Objasniću sve intuitivno, sa primerima iz stvarnog sveta, i videćeš da je matematika za 3D grafiku zapravo elegantna i logična kad se pravilno objasni.
📖 Dalje čitanje: