„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés
Elkezdtem megírni az árnyékok részt →A harmadik házihoz szükséges elmélet |
|||
| 942. sor: | 942. sor: | ||
* Ez máris egy fokkal jobb, de sajnos a valósághűbb környezet választása nem oldotta meg minden problémánkat, hanem inkább újakat vetett fel, például, hogy a kocka nem vet árnyékot a síkra, mint ahogy azt a valóságban tenné. | * Ez máris egy fokkal jobb, de sajnos a valósághűbb környezet választása nem oldotta meg minden problémánkat, hanem inkább újakat vetett fel, például, hogy a kocka nem vet árnyékot a síkra, mint ahogy azt a valóságban tenné. | ||
* A sík azon részeinek kéne árnyékban lenni, ahol valami útban van a fényforrásból az adott pontba menő sugárnak. Ezt úgy tudjuk felhasználni, hogy ha a fényforrásból egy sugarat lövünk az adott pont felé, és megnézzek, hogy a legközelebbi tárgy, amit eltalált, az az-e, amit éppen rajzolni akarunk, vagy praktikusan a metszéspont fényforrástól vett távolsága megegyezik-e, az adott pont távolságával a fényforrástól. Mert ha nem, akkor amit rajzolni akarunk az árnyékban van. Egy másik ezzel ekvivalens módszer, hogy a tárgyból lövünk egy sugarat a lámpa felé, és ha nem metsz semmit, vagy amit metsz, az távolabb van mint a fényforrás, csak akkor számolunk megvilágítást. | * A sík azon részeinek kéne árnyékban lenni, ahol valami útban van a fényforrásból az adott pontba menő sugárnak. Ezt úgy tudjuk felhasználni, hogy ha a fényforrásból egy sugarat lövünk az adott pont felé, és megnézzek, hogy a legközelebbi tárgy, amit eltalált, az az-e, amit éppen rajzolni akarunk, vagy praktikusan a metszéspont fényforrástól vett távolsága megegyezik-e, az adott pont távolságával a fényforrástól. Mert ha nem, akkor amit rajzolni akarunk az árnyékban van. Egy másik ezzel ekvivalens módszer, hogy a tárgyból lövünk egy sugarat a lámpa felé, és ha nem metsz semmit, vagy amit metsz, az távolabb van mint a fényforrás, csak akkor számolunk megvilágítást. | ||
* Technikailag mindkét algoritmust fogjuk használni. A második - bár bonyolultabbnak tűnhet - de irányfényforrásokra csak az módszer működik. Az irányfényforrások ugyanis végtelen távol vannak, ahonnan nem tudok elindulni, viszont a felületi pontból a fény irányába el tudunk. A pont fényforrások esetén viszont az első algoritmus egyszerűbb egy picivel. | |||
* Fontos megjegyezni, hogy pl. irány fényforrások esetén a sugarat nem indíthatjuk pontosan a felületi pontról, hiszen akkor az ahhoz legközelebbi metszéspont maga a felületi pont lenne amiből indítottuk. Ez persze nem mindig teljesülne, a számolási pontosság miatt, ezért az anyag kisebb foltokban lenne árnyékos, amit "árnyék pattanás"-nak hív a szakirodalom (shadow acne). A megoldás erre, hogy az indításkor a kezdő pontot eltoljuk egy kis számmal, epszilonnal a haladási iránnyal. Pl. 0.0001f-el. A pont fényforrás esetén is szükség van erre, csak ott a távolság összehasonlításánál. | |||
* Egy lehetséges implementáció: | |||
<br/> <syntaxhighlight lang="c"> | |||
case Light::Directional: { | |||
// Lőjjünk egy sugarat a fényforrás irányába | |||
Ray shadow_checker = {inter.pos - 1e-3*light.dir, -light.dir}; | |||
Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker); | |||
if(shadow_checker_int.is_valid) { | |||
break; // Ha bármivel is ütközik, akkor árnyékban vagyunk | |||
} | |||
/* Megvilágítás számolása */ | |||
} | |||
case Light::Point: { | |||
Ray shadow_checker = {light.pos, (inter.pos - light.pos).normalize()}; | |||
Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker); | |||
if(shadow_checker_int.is_valid && | |||
(shadow_checker_int.pos-light.pos).length() + 1e-3 < (inter.pos-light.pos).length()) { | |||
break; // Ha bármivel is ütközik, ami közelebb van a fényhez, mint mi, akkor árnyékban vagyunk | |||
} | |||
/* Megvilágítás számolása */ | |||
} | |||
</syntaxhighlight> <br/> | |||
Az így létrehozott árnyékok pont fényforrás esetén így néznek ki: | |||
<div style="text-align:left;margin:0px auto;"> | |||
http://i.imgur.com/E8mjq9d.png | |||
</div><br/> | |||
----- | ----- | ||