Láttuk, hogy hogyan működik a Fény és az emberi látás és definiáltuk, a renderelés fogalmát, ami valami módon létrehoz egy képet egy virtuális világból, és a monitorra vetíti azt: A képalkotás alapfogalmai.
Most nézzük meg, kicsit közelebbről hogyan is történik mindez, hogyan zajlik a renderelés!
Az alábbi technikákat persze nem kell nekünk manuálisan lefejleszteni, ahhoz, hogy játékmotor alatt programozzunk. Erre való a játék motor render engine-je. Ám hosszú távon ahhoz, hogy olyan vizuális világot kapjunk, amilyet megálmodtunk fontos megérteni, mi történik a háttérben képszintéziskor. Csak így fogunk tudni hatékonyan beállítani és leprogramozni egyedi megjelenítést.
Globális illumináció / Global Illumination
A fények működésével foglalkozó leckében tárgyalt fizikai jelenségek leszimulálhatók számítógéppel is. A fényforrás kilövell virtuális fényrészecskéket magából, amik össze-vissza pattognak virtuális felületeken szimulálva a fotonok viselkedését. A kamera felületére ezen pattogás után bejutó részecskék iránya, színe és mennyisége alapján áll össze a megjelenített képet.
A fent leírt renderelési stratégiát globális illuminációnak nevezik, ám leszimulálása valós időben a jelen technológiai szinten lehetetlen, ezért a valós idejű játékok megjelenítése nem így működik.
A számítógépes grafikának olyan egyéb területein, amin a renderelés sebessége nem annyira kritikus és szűkös, mint a valós idejű játékokban, nagyon is dominálnak a globális illuminációs technikák. Erre példa a lehet az animációs filmgyártás vagy az ipari terméktervezés.
Más terminológia szerint a globális illumináció egy tágabb fogalom. Eszerint nem csak az az algoritmus számít globális illuminációnak, ami egyedi virtuális fotonok térbeli pattogását és szóródását egyenként szimulálja, hanem egyéb számítógépes technikák is, amik valami módon hatékonyan érik el a valós fizikához hasonló látványt. A fogalom eszerinti bővített verzióját használva a Unity és egyéb valós idejű motorok is képesek manapság globális illuminációra.
Ennek legfőbb eszközei Unity-ben a:
A globális illumináció célja tehát, hogy magas színvonalú realisztikus látványt érjünk el. Ez gyakran nem lehetséges egy adott célplatformon. Más esetekben mikor egy fajta stilizált látvány a célunk, nincs is szükségünk ilyen szintű realizmusra, sőt lehet, hogy kifejezetten kerülni szeretnénk. A következőkben nézzük meg, hogy milyen egyéb kevésbé erőforrásigényes technikák léteznek.
Minden esetre kiemelendő, hogy számítógépes grafikában sosem pontosan a valós fizikát szimuláljuk, annak pontos szabályai szerint. Mindig egy egész sorozatát használjuk fel processzor és videókártya kímélő “csalásoknak”. Ez még a legvalószerűbb globális illuminációs technikákra is igaz.
RayCasting
Képzeljük el, hogy behunyjuk az egyik szeműnket és a nyitva hagyottal átnézünk egy ablakon. Ezt az ablakot felosztjuk apró négyzetrácsokra. Ennek a rácsnak minden kis eleme csak egy színt vehet fel. Ezt a színt úgy kapjuk meg, hogy egy egyenes vonalat húzunk a szemünktől a rácskocka közepéig majd azt addig hosszabbítjuk, ameddig az nem találkozik egy objektummal.
Az ablakunk persze a képernyőnek felel meg, az ablak négyzetrácsa pedig a pixeleknek. Minden egyes pixelt olyan színre színezünk, ami az eltalált objektum (vagyis annak textúrájának) színe az adott pontban.
Mindez természetesen elvégezhető egy programkóddal. Meg is lennénk kész a primitív de működőképes rendererünk. Ezt a technikát, amit alkalmaztunk RayCasting-nak nevezik.
Általában persze nem áll meg itt a történet. Egy pixel színe nem csak attól függ, hogy milyen objektum van mögötte, de attól is, hogy az eltalált ponthoz és a betekintés szögéhez képest hol helyezkednek el fényforrások.
Vetett árnyék: Minden eltalált pontból indítsunk egy újabb sugarat a fényforrás felé is. Ha akadálytalanul odaért a sugár, akkor a fény megvilágítja a pontot, ha ütközik valamivel, akkor az a valami árnyékot vet az eltalált pontra. Ha nem pontszerű, hanem irányfényt használunk akkor a sugarat egyszerűen csak ebbe az irányba kell elindítani.
Most nézzük át a diffúz, spekuláris és ambiens árnyalási stratégiákat RayCasting esetén! Ezen árnyalások definicíója itt olvasható Fények és Skybox
Diffúz árnyalás / Diffuse lighting: Emlékezzünk, diffúz árnyalás esetén a világosság csak attól függ, mennyi fény esik egy adott területre. Ha számításba vesszük azt milyen távol van a fényforrás és sugara milyen szöget zár a be felület normáljával, akkor megkaphatjuk ezt.
Magasabb szögben érkező fény jobban megvilágítja a felületet, mert egységnyi fénymennyiség kisebb területen oszlik el, ugyanígy ha közelebb van a fényforrás, az is növeli az egységnyi felületre eső fényt.
Spekuláris árnyalás / Specuar lighting: A szem és fény irányába tartó sugarak közti szöget kell felhasználni. Minél tompább ez a szög annál erősebb a tükröződés, a becsillanás mértéke.
Ambiens árnyalás / Ambient lighting: Legtöbb esetben az ambiens fényt a lehető legeszerűbben csaljuk oda RayCasting alapú renderelés esetén: Szimplán minden pixelhez hozzáadunk egy fix színértéket.
Ray Tracing
Módosítsunk egy kicsit a fenti megközelítésen. Raycasting esetén minden pontot egy raycast adott meg vagy hogyha vetett árnyékokat is szerettünk volna, akkor fényenként még egy.
Mi van akkor, ha egy fényrészecske pattanását (tükröződését) is szimuláljuk minden egyes pixelre?
Mikor egy valódi foton elér egy felületet, annak tulajdonságaitól függően részben elnyelődik és részben visszapattan. Ezt szimuláljuk Ray Tracing-gel csak visszafelé követve a részecskék útját a kamerából indulva. Először minden pixel irányában kibocsátunk egy részecskét hasonlóan a Ray Casting fejezetben tárgyalt módszerhez. Ha elér egy ilyen virtuális visszafelé menő foton egy felületet, akkor nem csak azt nézi meg, hogy a fények közvetlenül hogy világítják meg, hanem a material beállításaitól függően tovább pattan több véletlenszerű irányba is. Ez aztán tovább ismétlődik rekurzívan: A pattanó fotonok is tovább pattannak és sokszorozódnak egy felület elérésekor. Minden egyes pattanás esetén azonban csökken annak mértéke, hogy ezen új részecske mennyire szól bele a pixel színébe: Emlékezzünk minden egyes eredeti foton egy pixelből indult, szóval minden pattanása is csak ezen pixel színét hívatott megállapítani. Minden tovább pattant részecske egy ponton elér egy olyan állapotot, hogy hozzájárulása a pixel színéhz már elhanyagolható. Ekkor nem érdemes folytatni a szimulációt.
A Ray Tracing technikák trükkje, a visszafelé irányú gondolkodás, ami sokkal gyorsabb fizikai alapú globális illuminációnál, hiszen a fényforrások által kibocsátott fotonoknak csak egy töredéke jut a retinába vagy a virtuális kamerába. Kibocsátáskor azonban nem dönthető el melyek lesz ezek a részecskék. A Ray Tracing elkerüli ezt a pazarlást és emellett hasonlóan realisztikus hatást ér el.
A technikával nem kell külön számolni vetett árnyékokat, diffúz, spekuláris és ambiens árnyalást. Ezek mindegyike egyszerre jelenik meg a felületek fény szórási tulajdonságaiból.
Sok egyéb járulékos előnye is van ennek a technikának. Felületeket és anyagokat tudunk átlátszóvá és valóságosan tükröződővé tenni, valamit fókusztávolságot adni a renderhez különösebb extra “trükkök” beiktatása nélkül is. Látni fogjuk, hogy mindez a manapság is elterjedt klasszikus valós idejű Render Pipeline esetén nem ilyen egyszerű.
A gond a Ray Tracing-gel sajnos továbbra is, az hogy sok esetben nagyságrendekkel több számítást igényel, mint a hagyományosabb technikák. Emellett azonban megemlítendő, hogy a valós idejű felhasználói szintű Ray Tracing a cikk írásának idén (2023) már létezik, még ha nem is elterjedt.
Az Nvidia 20-as szériájával kezdve a cég speciális hardvert ad a videokártyáihoz, ami segítségével hatékonyabban számolhatók az Ray Tracing alapját adó egyedi raycast-ok. (Valamit hardveresen megoldani mindig optimálisabb lesz, mint szoftveresen.)
A korábbi raszterizációs technológiát mindez persze nem váltotta le egyik napról a másikra. Sőt még a mai Ray Tracing-et kihasználó játékok is mind valamiféle hibrid renderert használnak. Mára azonban már elég hosszú a lista, ami az olyan játékok sorát tartalmazza, ami valamilyen szinten épít a Ray Tracing-re:
Raszterizáció: Klasszikus valós idejű renderelés
Sajnos minél jobban optimalizálni szeretnénk a képalkotást, annál távolabb kell kerülnünk a valós fizika működésétől és azok egyes jellemzőit utólagosan csalni vissza egyedi okos mérnöki trükkök segítségével.
A valaha készült 3D-s videójátékok 99%-a az úgynevezett raszterizáció technikája segítségével renderel képet a virtuális világból. Ennek lényege, hogy egyenként minden objektumot a többitől függetlenül raszterizálunk vagy pixelesítünk, ami annyit jelent, hogy egyből kiszámoljuk a pixeleket ott, ahol megjelennek ezek a képernyőn. Bár ezen módszer sokkal gyorsabb tud lenni, mint fizika alapú render technikák, nagy hátránya hogy az egyes objektumokra így nem hat a környezetük.
Ezáltal elvesztünk olyan alapvető fizikai jelenségeket, mint árnyékok, tükröződés, fénytörés, fényvérzés, és realisztikus ambiens árnyalás. Ezek azok a tulajdonságai a valósághű képalkotásnak, amiket valamiképp utólagosan vissza kell csalnunk a játékba. Ez nem csak a render engine-ek fejlesztőinek kihívás, de a játékfejlesztők életét is komplikálja.
A raszterizáció felbontható egyedi lépésekre. Minden egyes lépésnek van egy elvárt bemenete és egy kimenete. Ezen lépéseken a virtuális világ adatai, mint egy gyártósoron végig haladnak, míg legvégül elkészül a rasztergrafikus (pixeles) kép. Ezt a metaforikus gyártósor gyakran inkább csővezetékként szokás elképzelni, innen a neve: Render Pipeline.
A következő fejezet foglalkozik a Render Pipeline-ok részleteivel: A Render Pipeline-ok