Ray tracing alapok Flag'98 Coder-l előadás TomCat/Abaddon[tomcat@szif.hu]

Ez a dokumentum azt célt szeretné szolgálni, hogy a kedves coderek ismerkedjenek meg a ray tracing alapjaival és így a jővőben minél több olyan magyar demo vagy intro készüljön, ami ezt a technikát is használja. A doksi a köv. részekből áll:

A fotorealisztikus ábrázolás jelentőségét két részre bonthatjuk, egyrészt a valóság nagyon pontos mását készíthetjük el vele, másrészt pedig a fantáziánkat elengedve, olyan képeket alkothatunk, melyeken a megjelenő elképzelt világ a nézőben hihető valóság érzetét kelti. S minél pontosabban modellezzük a fény és a látás fizikai tulajdonságait, a kapott kép annál valósághűbb lesz, de a modell számítási igénye is ezzel párhuzamosan nő.

Figyeljétek meg a képen a modell jellegzetes jegyeit: az objektumok egymásra vetett árnyékait, a többszörös tükröződéseket, a fény csillanásait !

Az egyszerű objektumokból bonyolultabbakat is összeállíthatunk, például ez a csiga több ezer gömbből áll.

A ray tracing lényege röviden a következő: egy háromdimenziós koordinátarendszerben matematikai függvényekkel leírt környezetből fotoszerű képet számolunk ki a fénytan törvényeinek segítségével. Ehhez a fény útját kell nyomonkövetni, vagyis, hogy a fényforrás által kibocsátott fotonok milyen úton jutnak a szemünkbe, közben milyen tárgyaknak ütköznek, azok pedig a fény mely részét nyelik el, eresztik át vagy tükrözik vissza. Az ábrán a szemünkbe érkező fény útja figyelhető meg. Megjegyzés: ez a modell a fény hullámtulajdonságát elhanyagolja.

De mivel a fényforrás legtöbb fotonja nem jut a szemünkbe, ezért sokkal gyorsabb visszafelé végigjárni a fény útját, s megnézni azt, hogy az az irány, amelyben nézünk az eltalál-e fényforrást.

Mi végeredményként egy digitális képet szeretnénk, ezért konkrétizálva a feladat az, hogy mind enegyes képpontban találjuk meg az oda beérkező fények színét.

Nézzük mi is kell ahhoz, hogy a szemtől elindítsunk egy sugarat:

  1. Kell az a pont ahonnan nézünk ill. ahová nézünk ( E és M ).
  2. Kell a függőleges és a vízszintes látószög ( théta és ).
  3. Egy felfelé mutató vektor, amelyből tudjuk, hogy a néző a feje tetején áll-e vagy se ( U ).
  4. Valamint a kívánt képpontok száma ( x0 és y0 ).

Ezek alapján egy duplaciklussal minden képponthoz indíthatunk egy-egy sugarat E-ből S irányába. A ciklusváltozó Px és Py lesz, melyek értéke -1-től 1-ig nő x' és y' léptékkel. Bővebben lásd az ábrát, ahol:

S = M + Px * H + Py * V
x' = 2 / x0
y' = 2 / y0
H = ( d * tan( théta ) ) * X
V = ( d * tan(  ) ) * Y
X = G × U
Y = X × G
G = M - E
d = | G |
Ha az adott képpontból elindítottunk egy sugarat, akkor meg kell vizsgálni, hogy melyik objektumot találja el először, azaz melyik tárgy látszik abból a pontból. Ez egy minimum keresés, ami a sugár és a tárgyak metszéspont-távolságainak a minumumát keresi. Ha megvan a tárgy, akkor további metszéspont vizsgálatokat igényelnek az árnyékok, a tükröződések és a fénytörések kiszámításai.

A ray tracing legidőigényesebb feladata a metszéspont keresés. A sugarat az egyenes egyenletével írjuk fel: X = P + D * t. Pontosabban csak egy fél egyenesnek értelmezzük, mert a nézőpont mögötti tér nem érdekes. Tehát a t csak pozitív értéket kaphat.

Példaként nézzük a gömb egyenletét: ( X - C ) * ( X - C ) = r * r.
A metszéspont mindkét egyenletet kielégíti, ezért X helyére beírjuk a sugár egyenletét. Így egy másodfokú egyenletet kapunk,
ahol a = D ˇ D, b = 2 * D ˇ V, c = V ˇ V - r * r és V = P - C. A megoldóképlet diszkriminásának negatív, nulla és pozitív értékeihez tartozó fizikai jelentéseket az ábra mutatja.

Mivel a ray tracing a legtöbb időt a rengeteg metszéspont vizsgálattal tölti, ezért célszerű ezek számát csökkenteni.

Tegyük fel, hogy a képen látható számok rengeteg apró háromszögekből állnak össze. Namármost ha a szemünktől indított sugár egyetlen számot sem talál el, akkor is végig kell nézni minden kis háromszöget a metszéspont keresésnél. Ezen a problémán a befoglaló testek ( bounding volumes ) használatával segíthetünk. Bármely térbeli test egyben egy ponthalmaz is, amely köré burkoló felület készíthető el. Mi ezt a burkoló felületet az úgy nevezett befoglaló test felületeként értelmezzük. Például adjunk meg minden számhoz egy befoglaló gömböt, s amikor valamelyik szám háromszögeinek a metszéspontját keresük, akkor először az őt befoglaló gömböt vizsgáljuk meg, s ha azt nem metszi a sugár, akkor a háromszögeket már meg sem kell vizsgálni. Így ha semmit sem talál el a szemsugár, akkor csak pontosan annyi metszéspont vizsgálatra van szükség, amennyi számunk van.

Nos igen, ez az eljárás egyertelműen gyorsított a metszéspont kereséseken. De most vessünk ismét egy pillantást az ábrára. Mi lenne, ha az ábrán látható négyzet egy befoglaló téglatest vetülete lenne. Akkor az valószinűleg megint gyorsítana a metszéspont keresésen, hiszen például ha a szemsugár nem találna el tárgyat, akkor a hat befoglaló gömb helyett csak egy befoglaló téglatestre kéne elvégezni a metszéspont vizsgálatot. Tehát a fejlesztés útja a hierarchikus befoglaló tárgyak használata lesz.
A kédés csak az, hogy milyen struktúra lenne a legmegfelelőbb ?

Ezen az ábrán kb. 8000 gömb van, ezek hierarchiája jól látható, de ezt a hierarchikus csoportosítást a géppel automatikusan elvégeztetni nem egyszerű feladat.

Végül vizsgáljuk meg egy jelenet matematikai leírását:

Ez a hét gömb kiszámolva így néz ki: