„Számítógépes grafika házi feladat tutorial” változatai közötti eltérés
A spekuláris modellnél célszerűbb Blinn-Phongot használnom |
|||
| 1 099. sor: | 1 099. sor: | ||
De mit jelent az, hogy a "közelébe"? Mennyire a közelébe? És a normál közelébe mennyivel gyengébb ez a hatás, mint pont a normálban. A lapok irányát egy harang görbe jellemzi. Hogy megtudjuk, hogy abba az irányba a lapok hányadrésze néz, ami a visszatükröződésnek kedvez, be kell helyettesítenünk a normál eloszlás sűrűségfüggvényébe. A képlet nem bonyolult, de van benne egy exponenciális függvény, aminek kiszámítása lassú. Viszont skaláris szorzattal egy koszinuszt ki tudunk számolni, ami egy picit hasonlít a haranggörbére. Ha a koszinusznak vesszük egy polinomját, pl az a*cos(x)^b, azzal nagyon jól közelíteni lehet a haranggörbét. | De mit jelent az, hogy a "közelébe"? Mennyire a közelébe? És a normál közelébe mennyivel gyengébb ez a hatás, mint pont a normálban. A lapok irányát egy harang görbe jellemzi. Hogy megtudjuk, hogy abba az irányba a lapok hányadrésze néz, ami a visszatükröződésnek kedvez, be kell helyettesítenünk a normál eloszlás sűrűségfüggvényébe. A képlet nem bonyolult, de van benne egy exponenciális függvény, aminek kiszámítása lassú. Viszont skaláris szorzattal egy koszinuszt ki tudunk számolni, ami egy picit hasonlít a haranggörbére. Ha a koszinusznak vesszük egy polinomját, pl az a*cos(x)^b, azzal nagyon jól közelíteni lehet a haranggörbét. | ||
A leggyakoribb megoldás, a Blinn-Phong modell, a visszaverődési normál (a fényből a felületi pontba menő, és az abból a szemünk felé mutató egységvektorok átlaga) és a tényleges felületi normál által bezárt szög koszinuszát használja. A visszaverődési normál, vagy más nevén a félszög-vektor jele legyen 'H' (mint Half-angle), a normál pedig 'N'. | |||
A koszinusz, amit használni akarunk a <code>dot(H, N)</code> képletből áll elő. A negatív érték nekünk nem jó, és ennek még kell vennünk egy polinómját, így végül a <code>specular_power = pow(max(dot(H, N), 0), shininess)</code> képletet kapjuk. | |||
< | |||
A spekuláris anyag egyben diffúz is. A spekuáris megcsillanás (specular_power * specular_color) hozzáadódik a diffúz megvilágításból származó színhez. | A spekuláris anyag egyben diffúz is. A spekuáris megcsillanás (specular_power * specular_color) hozzáadódik a diffúz megvilágításból származó színhez. | ||
| 1 124. sor: | 1 108. sor: | ||
<br/> <syntaxhighlight lang="c"> | <br/> <syntaxhighlight lang="c"> | ||
Vector L = light.dir.normalize(), V = (camera.pos-inter.pos).normalize(); | |||
Vector H = (L + V).normalize(), N = inter.normal; | |||
float specular_power = pow(max(dot(H, N), 0.0f), shininess); | |||
accum_color += specular_power * light.color * specular_color; | accum_color += specular_power * light.color * specular_color; | ||
</syntaxhighlight> <br/> | </syntaxhighlight> <br/> | ||
Itt se feledkezzünk el az árnyékokról. Szerencsére az árnyékszámítás itt is teljesen ugyan az. | Itt se feledkezzünk el az árnyékokról. Szerencsére az árnyékszámítás itt is teljesen ugyan az, ezért célszerű a láthatóságot egy külön függvényben eldönteni. | ||
A 'shininess' meghatározása teljesen mértékben hasra-ütésre, próbálgatással szokott menni. Én személy szerint a kettőhatvány shinnines értékekkel szoktam először próbálkozni (8 - 16 - 32 - 64 a leggyakoribb nálam), és utána esetleg "finom hangolom" az értéket, az alapján, hogy melyik éréték néz ki jól. | A 'shininess' meghatározása teljesen mértékben hasra-ütésre, próbálgatással szokott menni. Én személy szerint a kettőhatvány shinnines értékekkel szoktam először próbálkozni (8 - 16 - 32 - 64 a leggyakoribb nálam), és utána esetleg "finom hangolom" az értéket, az alapján, hogy melyik éréték néz ki jól. | ||
| 1 142. sor: | 1 122. sor: | ||
Például: [[Média:Grafpp_raytrace_specular_highlights.cpp|Spekuláris megcsillanás egy kockán]] | Például: [[Média:Grafpp_raytrace_specular_highlights.cpp|Spekuláris megcsillanás egy kockán]] | ||
http://i.imgur.com/ | http://i.imgur.com/VBb5ODK.png | ||
=== A tökéletes tükör === | === A tökéletes tükör === | ||
| 1 148. sor: | 1 128. sor: | ||
A mikroszkopikus tükrök figyelembevételével a fényforrások fénye tükröződni tud. De mi van a valódi tükrökkel? Amikben más objektumok képeit is látjuk, nem csak a fényforrások hatását? Sugárkövetéssel ilyen tükröket renderelni meglepően egyszerű. Az egyetlen dolog amit a tükör tulajdonságú anyag csinál a modellünkbe az az, hogy a tükröződés irányába továbblövi a sugarat. | A mikroszkopikus tükrök figyelembevételével a fényforrások fénye tükröződni tud. De mi van a valódi tükrökkel? Amikben más objektumok képeit is látjuk, nem csak a fényforrások hatását? Sugárkövetéssel ilyen tükröket renderelni meglepően egyszerű. Az egyetlen dolog amit a tükör tulajdonságú anyag csinál a modellünkbe az az, hogy a tükröződés irányába továbblövi a sugarat. | ||
Először is ki kell tudnunk számolni, hogy 'N' normálvektorral rendelkező tükör merre ver vissza egy beérkező 'I' sugarat. Azt tudjuk, hogy a három vektor egy síkban van, és a beesési szög megegyezik a visszaverődési szöggel. De mégse így fogunk számolni, egyszerű vektor műveletekkel is ki lehet fejezni. | |||
http://i.imgur.com/RsTWJVC.jpg | |||
Próbáld a visszavert sugarat csak a négy alapművelet és a skaláris szorzás segítségével kifejezni. | |||
A legegyszerűbb megoldás: | |||
<br/> <syntaxhighlight lang="c"> | |||
inline Vector reflect(Vector I, Vector N) { | |||
return I - (2.0 * dot(N, I)) * N; | |||
} | |||
</syntaxhighlight> <br/> | |||
Ezt felhasználva a tükröződést implementálni már egyszerű, pl.: | |||
<br/> <syntaxhighlight lang="c"> | <br/> <syntaxhighlight lang="c"> | ||