Ray Tracing: Tieňovanie

Vo svete už pomerne ťažko nájdeme objekty, ktoré nie sú nejakým spôsobom osvetlené, pokiaľ sa priamo nejedná o absolútnu tmu. Takže objekty buď vrhajú nejaký tieň v rôznej forme, a/alebo daný objekt obsahuje vlastný tieň. V každom prípade tieňovanie ako také pridáva objektom realistický výraz. Z hľadiska vektorového počtu v počítačovej grafike je možné simulovať tieň (ako aj ostatné optické efekty typu odrazu a podobne) pomocou normálového vektoru.

Takže normálový vektor alebo tiež „normála“, k nejakej ploche je vektor, ktorý je kolmý na plochu v danom bode. Zvyčajne sa označuje písmenom n. (obrázok od Wolfram)

wolfnnn

Keďže takýto vektor je kolmý k ploche v nejakom bode, tak pre náš objekt gule bude tento vektor v každom bode rôzny, to znamená, bude mať rôzny smer. Práve táto vlastnosť, smerovosť vektora, nám bude simulovať rôzny odtieň v každom bode. Ak takéto smerovanie prispôsobíme smeru svetelných zdrojov, tak bude možné simulovať smer osvetlenia a teda tieňovania. Vzhľadom k tomu, že nás bude zaujímať len smer normálového vektora, tak nebude potrebné vedieť veľkosť tohto vektora a preto sa takto „znormovaný“ vektor nazýva aj ako jednotkový vektor, ktorý ako už z názvu vyplýva, označuje vektor s hodnotou jedna, teda jednotkovou a slúži len na určenie smeru. (obrázok od ScratchPixel)

sshaAko bolo spomenuté, normálový vektor je vektor kolmý na plochu v nejakom bode, napr. p (point). Takže, aby sme našli normálový vektor v bode p, potrebujme zostrojiť dotyčnicu k ploche v bode p (dotyčnica v priestore je dotyková rovina) a potom k tejto dotykovej rovine zostrojiť vektor kolmý na túto dotykovú rovinu. Teda, odstupňovaný jas, ako je možné vidieť na objekte gule, je závislý na uhle normálového vektora. Takýto „odstupňovaný“ proces, alebo sklon funkcie sa v matematike nazýva gradient.

Výpočet takého normálového vektora bude v každom prípade závisieť od konkrétnej geometrie objektu. V našom prípade bude nájdenie normálového vektora pomerne jednoduché. Ak poznáme polohu bodu na objekte gule a jej stredové súradnice, tak normálový vektor získame odčítaním polohového bodu p od stredu objektu gule zo súradnicami c:

\(\vec{n} = \vec{p} – \vec{c}\)

Z hľadiska programového kódu to napíšeme priamo ako jednotkový vektor:

Môžme si všimnúť, že sme použili parameter t, to znamená, že už nám nebude stačiť len zistenie, že sme našli nejaký priesečník, ale potrebujeme vedieť aj konkrétnu hodnotu v tomto bode. Takže za týmto účelom upravíme diskriminant nasledovne:

Týmto zabezpečíme, že táto funkcia bude poskytovať ako návratovú hodnotu parameter t, teda konkrétne riešenie. Práve z toho dôvodu sme zmenili návratovú hodnotu funkcie hit_sphere() z pravdivostnej hodnoty bool na číselnú hodnotu typu float.

Na záver ešte upravíme funkciu color(), kde si budeme všímať len kladné hodnoty výsledkov priesečníka:

Výsledok bude vyzerať nasledovne pre výpočet v jednom smere:

koulaSH

Alebo pre všetky smery (úpravou Vector3(n.x()+1, n.y()+1, n.z()+1)):

koulaSH

Takýmto spôsobom je možné zobrazovať v tomto prípade zatiaľ len vlastný tieň objektu. V ďalšej časti bude uvedená určitá metóda na pridávanie ďalších objektov do scény.

You may also like...