Skip navigation

Anyagok

Előismeret

Mint már említettük, a tárgyak színe a fény és az anyag kölcsönhatásából áll elő. A fényekkel megismerkedtünk az előző részben, ahol érintőlegesen már találkoztunk az anyagokkal. Most részletesebben tárgyaljuk ezek közül az alábbiakat.

  • Material ősosztály és alap anyagjellemző (MeshBasicMaterial).
  • Lambert (diffúz) megvilágítás képpontonkénti (per-fragmentárnyalással (MeshLambertMaterial).
  • Phong (diffúz + spekuláris) megvilágítás képpontonkénti (per-fragment) Phong árnyalással (MeshPhongMaterial).

A megértést segíti, ha tisztában vagyunk a megvilágítási modell és árnyalás fogalmakkal. Ezeket az oldal végén, a kiegészítő anyagrészben mutatjuk be.

Fontos!

A MeshLambertMaterial működése alapvetően megváltozott az r144 kiadásban! A korábbi csúcspont-alapú (per-vertex) árnyalásról képpontonkénti (per-fragment) árnyalásra írták át! A korábbi működésnek megfelelő anyag osztályt elérhetjük a példák között található MeshGouraudMaterial.js fájlban. Ha használni szeretnénk, a fájlt külön importálni kell a programunkba. Erre a 03_02_ThreeJsMaterialTester.html programban találhatunk példát. Akkor érdemes ezt a régi megközelítést használnuk, ha a megvilágítási számítások miatt nagyon lelassulna a programunk futása, ugyanis a per-vertex megközelítés sokkal kevesebb számítást igényel, és szerencsés esetben nem látunk nagy különbséget a MeshLambertMaterial-hoz képest.

A Three.js Material oszálynevekben keveredik az árnyalási algoritmus és a megvilágítási algoritmus megjelenése. A Gouraud árnyalás, a Lambert megvilágítási egyenlet, a Phong pedig mindkettő. MeshLambertGouraud, MeshLambertPhongMaterial (vagy MeshLambertPerFragmentMaterial) és MeshPhongPhongMaterial (vagy MeshPhongPerFragmentMaterial) egyértelműbb megnevezések lennének.

További anyagtípusok

A Three.js további anyagtípusokat is definiál, amikkel itt részletesen nem foglalkozunk. A dokumentációban utána lehet nézni az alábbiaknak.

Az anyagokról és használati módjaikról az alábbi online dokumentációban olvashatunk részletesebben (angol nyelven):

Megfigyelés

Nagyon fontos tudni, hogy az egyszerű megvilágítási egyenletek nem veszik figyelembe, hogy a fényforrás és az objektum adott pontja között van-e más objektum. Így a fény mintha akadálytalanul "áthatolna" minden tárgyon, ami erősen sértheti a valósághűséget. Ha a takarásokat használni szeretnénk, akkor az árnyékolást be kell kapcsolni!

Megvilágítási modell és árnyalás (kiegészítő anyag)

A fényhatások jobb megértéséhez célszerű tisztázni az alapfogalmakat.

A megvilágítási modell definiálja a számításokat, amelyekkel kialakul egy objektumpont képernyőn megjelenő színe. Gyors megjelenítést igénylő esetekben jellemzően az alábbi három klasszikus modellt valósítják meg.

  • Az ambiens megvilágítás a legegyszerűbb modell, amelyben csak a fényforrás és az anyag színe játszik szerepet, a fény beérkezési iránya nem. Környezeti, szórt fénynek felel meg, amikor a fény nem közvetlenül érkezik az anyagra, hanem valamilyen közegen szóródva, többféle irányból (pl. a Nap fénye a felhőkön átjutva egy borult napon). Ezzel önmagában nem fogunk szép eredményt elérni, de a többi megvilágítási komponenst kiegészítheti egy globális fényhatással.



  • A diffúz megvilágítás esetén az egyenletben megjelenik a fény színe, az anyag színe és a fény felszínre esési szöge. Több fényforrás esetén minden fényre kiértékelődik az egyenlet, és az így kapott színeket elegyíti a rendszer. Az ambiens komponenssel kombinálva Lambert megvilágításnak nevezik.



  • A Phong megvilágítás a Lambertnél leírtak mellett figyelembe veszi azt is, hogy a megfigyelő (a kamera) hol található a felszínről visszaverődő fényirányhoz képest, és hogy milyen az anyag csillogási fényvisszaverő képessége. Amennyiben a visszaverődő fény a kamerába jut (a β szög 0 fok körüli), a fény színét látjuk, növekvő β szögek esetén egyre inkább a Lambert megvilágítás színe érvényesül. Egy csillogási paraméterrel szabályzhatjuk a β szögtől való függést.



A megvilágítási modellek tehát azt mondják meg, hogy egy adott pontban milyen szín alakul ki. Kérdés még, hogy ezeket az egyenleteket milyen pontokban, és ott milyen paraméterekkel értékeljük ki? Ez az árnyalás témaköre. Itt háromféle megoldás jelenik meg.

  • Egyszínű árnyalás esetén minden háromszöghöz 1 darab színt határozunk meg, például a háromszöget definiáló csúcspontok közül az elsőhöz tartozót, a három csúcsponthoz rendelt színek átlagát, vagy a háromszöget egy objektumként kezelve az objektumhoz rendelt színt, és ezt a színt használjuk a háromszög belső pontjainak kiszínezéséhez. Kevés számítást igénylő, nagyon gyors módszer, de az eredmény csak akkor elfogadható, ha eleve egyszínű háromszögeket szeretnénk modellezni.
  • A csúcspont-alapú, vagy angol terminológiával per-vertex árnyalás esetén a megvilágítási egyenleteket csak a háromszög csúcspontjaiban számítjuk ki, a háromszög belső képpontjai a csúcspontokban meghatározott színek alapján valamilyen számítási módszerrel előálló színt kapják. Vagyis a szín itt már képpontonként változhat. Egy klasszikus per-vertex algoritmus a Gouraud árnyalás, amikor a háromszög belső képpontjai a csúcspontokban számított színek interpoláltjaként számítódnak, vagyis a csúcspontoktól való távolság függvényében a három szín elegye adja a kitöltési színt. Nagy méretű háromszögek esetén a lokális fényhatások (például reflektorfény) torzulhatnak.
  • Jellemzően a képpontonkénti, per-fragment árnyalás adja a legszebb eredményt, de jóval több számítás árán. Ebben az esetben a belső képpontok mindegyikére kiszámítjuk a megvilágítási egyenleteket. Ha belegondolunk, egy háromszöghöz három csúcspont tartozik, belső képpont viszont lehet több ezer vagy millió darab is! Egy klaszikus per-fragment algoritmus a Phong árnyalás, ahol a fény felszínre esési szögének számítása történik a csúcspontokban definiált normálvektorok interpoláltjait használva. Normálvektorokkal a következő témakörben foglalkozunk majd.

Klasszikus OpenGL megvilágítási egyenletek (kiegészítő anyag)

A megvilágítási modell leírásában hivatkoztunk a megvilágítási egyenletek kiértékelésére, de ott azokat nem adtuk meg. A klasszikus OpenGL egyenletek az alábbiak.

Az ambiens megvilágítás esetén az eredmény szín (Iambiens) az ambiens fényre reagáló anyagi jellemző (ka) és az ambiens fény színének (Ia) komponensenkénti szorzataként áll elő. Megjegyezzük, hogy mindhárom vektor hármasként kerül megadásra a vörös, zöld és kék komponenseknek megfelelően, és [0, 1] közötti normalizált értékekkel bírnak. (Vagyis a [0, 255] formában megadott bemeneti szín és anyagjellemző értékeket előzetesen 255-tel osztani kell.)

I_{ambiens} = k_{a}I_{a}

A diffúz komponens esetén a fény felszínre érkezésének szöge is számít, ami a felület adott pontjában számított normálvektorához viszonyítva számítunk (α). A fény hatása csak akkor érvényesül, ha ez a bezárt szög a [-90, 90] fok tartományból kerül ki, egyébként "hátulról" érkezik és nincs hatása. Ez utóbbi esetet így kizárjuk. 90 fokos esetben a fény párhuzamosan "elsuhan" a felszín felett. Vegyük észre, hogy a koszinusz értéke ezen a szögtartományon nem negatív, így egy 0-hoz viszonyított maximum számítással dolgozhatunk. Amennyiben 0-val szorozzuk a komponenseket, azok értéke is 0 lesz, ami azt jelenti, hogy nem járulnak hozzá a képernyőn megjelenő objektumszín számításához.

I_{diffúz} = k_{d}I_{d}\max(\cos \alpha, 0)

A spekuláris komponens esetén a felületről visszaverődő fény és a kamera irányainak bezárt szöge (β), és a csillogási paraméter (shininess) is megjelennek az egyenletben.

I_{spekuláris} = k_{s}I_{s}\max(\cos \beta, 0)^{\textrm shininess}

A Lambert megvilágítás az ambiens és a diffúz, a Phong megvilágítás az ambiens, a diffúz és a spekuláris komponensek összegeként áll elő. Amennyiben egy csatornán az összeg meghaladja a maximum értékét, akkor az a maximummal kerül helyettesítésre.

I_{Lambert} = I_{ambiens} + I_{diffúz}

I_{Phong} = I_{ambiens} + I_{diffúz} + I_{spekuláris}

Amennyiben több fényforrás is van, mindegyikre kiértékelődnek az egyenletek, majd összegzésre kerülnek.

A megvilágítási egyenletek az OpenGL 2.0 verziótól nincsenek "beégetve" a rendszerbe, azokat tetszőlegesen valósíthatják meg az egyes implementációk az árnyalók (shader-ek) segítségével. A Three.js implementáció nagyjából a fentieknek felel meg, pár újdonsággal kiegészítve. (Ilyen kiegészítés például az ambiens és a diffúz komponens esetén a skalár intenzitás paraméter megadhatósága, az objektum saját fényének színe, vagy a Phong megvilágítás esetén a fémes hatást keltő változat választhatósága.)