Skip navigation

Perspektív és párhuzamos vetítés

Kamera nézeti beállítások

A kamerák, mint minden térbeli elhelyezkedéssel bíró objektum, rendelkeznek a pozíciójukkal és orientációjukkal kapcsolatos attribútumokkal és függvényekkel.

  • A kamera középpontjának térbeli helyzetét a position attribútummal adhatjuk meg. A kamera esetén ez az úgynevezett szem (eye) koordinátát jelenti.
  • A kamera orientáció beállítására nem javasolt a rotation attribútumot használni. Helyette az up attribútumot és a lookAt() függvényt használjuk az alább leírásra kerülő módon.
  • A kamera scale attribútumokat ne módosítsuk az alapértelmezett 1.0 értékről..

A kamera specifikus orientáció beállító lehetőségek az alábbiak. Részletesebb magyarázatot az oldal alján találunk kiegészítő anyagként.

  • A kamera up attribútumával a nézeti felfelé irányt adhatjuk meg. Ez alapértelmezetten a (0.0, 1.0, 0.0) felfelé (világ +Y) irányt jelenti. Ez biztosítja azt, hogy ha a kamera a célpontra fordul a lookAt() függvény hívásakor, akkor a kamera vetületi képen a horizont vízszintes marad. Az emberi nézőpont modellezésekor megfelelő. Amennyiben például repülőgép-szimulátort készítünk, akkor a repülési irány körüli nézeti elfordulást az up attribútum módosításával érhetjük el.
  • lookAt() függvénnyel szabályozhatjuk, hogy a kameránk melyik térbeli pontba nézzen.

A kamerát alapból nem kötelező a színtérhez adnunk, mert elég a rendereléskor megadnunk, hogy melyik színteret melyik kamerával szeretnénk megjeleníteni.

renderer.render( scene, camera );

Ha a kamerát más objektumhoz képest szeretnénk mozgatni, vagy hozzá más objektumot kapcsolnánk (például fényforrást), célszerű lehet hozzáadni a színtérhez.

Perspektív vetítés

Az emberi látást modellező perspektív vetítést a PerspectiveCamera objektummal érhetjük el. A térben párhuzamosan futó egyenesek látszólag egy pontban (a távlatpontban) metszik egymást, az objektum egyre távolabb kerülve a kamerától egyre kisebb méretű lesz.

Vetítés specifikus attribútumok

Az attribútumokkal a látómező méretét és a látószöget adhatjuk meg. A látómezők kívüli tárgyak nem kerülnek modellezésre!

fov Vízszintes irányú látótér tartomány (szögben).
Javasolt érték: emberi látás modellezésekor 50-90 között.
aspect Vízszintes és függőleges látótér tartomány aránya.
Javasolt érték (teljes ablakos modellezésnél): window.innerWidth / window.innerHeight.
near Közeli vágósík távolsága a kamerához.
Javasolt érték: 0.1.
far Távoli vágósík távolsága a kamerához.
Javasolt érték: 1000.
zoom Nagyítás léptéke.
Javasolt érték: 1.

Használati példa

// Böngésző ablakméret lekérése és méretarány számítása
HEIGHT = window.innerHeight;
WIDTH = window.innerWidth;
aspectRatio = WIDTH / HEIGHT;
// Kamera létrehozása és vetítési paramétereinek beállítása
camera = new THREE.PerspectiveCamera( 75, aspectRatio, 0.1, 1000 );
camera.position.z = 15;

Párhuzamos vetítés

A párhuzamos vetítést elsősorban mérnöki, tervezési feladatoknál használják. Az OrthographicCamera objektummal használhatjuk.

Vetítés specifikus attribútumok

left Bal oldali vágósík helye.
right Jobb oldali vágósík helye.
top Felső vágósík helye.
bottom Alsó vágósík helye.
near Közeli vágósík helye.
far Távoli vágósík helye.
zoom Nagyítás mértéke.

Használati példa

camera = new THREE.OrthographicCamera(
window.innerWidth / - 2,
window.innerWidth / 2,
window.innerHeight / 2,
window.innerHeight / - 2,
-500, 1000 );

camera.position.x = 200;
camera.position.y = 200;
camera.position.z = 200;
camera.lookAt( scene.position );

Vetítési paraméter változások érvényesítése

Ne felejtsük el, hogy a kamera vetítési paramétereinek módosulásakor meg kell hívni a kamera updateProjectionMatrix() függvényét!

A kamera vetítési paraméterei rendszerint megváltoznak, ha teljes ablakos modellezést végzünk és változik az ablak mérete. A bevezető példaprogramunk ismertetésekor ennek kezelésére is kitértünk.

A lookAt() függvény alaposabb vizsgálata (kiegészítő anyag)

A Three.js magasszintű API-ja részekre bontja a kamera nézet beállítását. Alacsonyabb szinten jellemzően a szintén lookAt() vagy hasonló nevű nevű függvényt hívjuk három darab háromelemű vektorral, vagy 9 darab számértékkel az alábbiak szerint:

  • eye_x, eye_y, eye_z: a kamera középpont térbeli elhelyezkedése (ez a Three.js position attribútuma),
  • target_x, target_y, target_z: a kamera vetítési célpontjának megadására (ezt a térbeli pontot adhatjuk meg a Three.js lookAt() függvényével),
  • up_x, up_y, up_z: a kamera nézeti felfelé irányának megadására (ez a Three.js up attribútuma).

Az alacsonyszintű lookAt() függvény egy 4x4 méretű mátrixot ad, amit a ModelView mátrix View komponenseként használhatunk fel. (Ennek részleteivel most nem foglalkozunk.) Az előző fejezetben tárgyalt object.matrix is rendelkezik lookAt() függvénnyel.

A koncepció lényegét az alábbi ábra magyarázza el.

Az ábra a térbeli világ XYZ koordináta-rendszer azon síkját mutatja, amelyet az eye  target és az up vektor irányok feszítenek ki. (Ha ezek egymással párhuzamos irányt adnak, akkor baj van, lásd később.)

A kamera nézeti irányát az eye és a target térbeli koordináták által definiált vektor adja. Az OpenGL (és így WebGL és Three.js) használati mód szerint az alapértelmezett kamera a negatív Z-tengely irányba néz, így a kamera koordináta-rendszer Z-tengelye ezzel ellentétes irányú lesz.

A kamera X-tengely irányát az up vektor és az eye  target vektor keresztszorzata adja. (Figyeljünk arra, hogy a keresztszorzat nem kommutatív művelet, vagyis a tényezők sorrendje nem cserélhető fel.) A keresztszorzat eredménye egy új vektor lesz, aminek az iránya az előző két vektor által kifeszített síkra merőleges lesz. Hosszát egység méretre kell alakítani, normalizálni kell. Ezt a vektor koordináták vektor hosszal való osztásával érhetjük el. Jobbsodrású koordináta-rendszer lévén a fenti ábrán ez a képernyő síkjából felénk kifelé mutató kamera X-tengely irányt jelent.

Vegyük észre, hogy a kamera koordináta-rendszer Y-tengely irányát általános esetben nem az általunk megadott up vektor fogja adni. Az up vektor csak egy nézeti orientációt jelent, ami nem kell merőleges legyen az eye target vektorra. A kamera Y-tengelyének viszont ilyennek kell lenni. Ezt egy újabb keresztszorzattal kapjuk a már meglévő kamera Z és X- tengely irányokat használva.

Bár komplikáltabbnak tűnhet, a valós életbeli kamera forgatásokat ezzel a paraméterezéssel kényelmesebben meg tudjuk adni.

Néhány dolog, amire figyeljünk modellezéskor.

  • Ha a kamera célpontja mozog, akkor az új koordinátáit minden megjelenítő (render) ciklusban meg kell adni a kamera objektumnak.
  • Vigyázzunk arra, hogy az up vektor és az eye → target vektor ne legyen egymással párhuzamos. Ilyen esetben a keresztszorzatuk nullvektort ad, ami nem értelmezhető térbeli irányként. Orientációs szabadsági fokot vesztünk, ahogy az előző fejezetben a gimbal lock tárgyalásakor láttuk.
  • Az objektum geometriai transzformációs attribútumokkal ellentétben a kamera nézeti beállításokat rögzített sorrendben kell végrehajtanunk a kódban! Először adjuk meg a két attribútumot (position és up) tetszőleges sorrendben, és csak ezek után hívjuk a lookAt() függvényt! Ennek oka, hogy a lookAt() függvény hívásakor a Three.js rögtön kiszámítja a nézeti orientációt reprezentáló egység kvaterniót, az nem a renderer.render() függvény végrehajtásakor történik!

A 4x4 méretű View mátrix számítása két lépésből áll. Azt szeretnénk elérni, hogy a kamera az általános térbeli elhelyezkedéséből és orientációjából a normalizált helyzetbe kerüljön: a (0, 0, 0) térbeli pozícióból a negatív Z-tengely irányba nézzen. Ehhez először eltolást kell alkalmazni az eye koordináták negatív értékével (így kerül a szem az origóba):

T = \left( \begin{matrix} 1 & 0 & 0 & -eye_x \\ 0 & 1 & 0 & -eye_y \\ 0 & 0 & 1 & -eye_z \\ 0 & 0 & 0 & 1 \end{matrix} \right)

Következő lépésként a forgatást kell alaphelyzetbe állítanunk. A koordináta-rendszer váltást a mátrix oszlopokban elhelyezett új X, Y és Z normalizált (egységnyi hosszúságú térbeli vektorral megadott) bázis irányok megadásával érhetjük el. Viszont itt egy már meglévő általános orientációból térünk vissza a világ X, Y és Z irányaihoz, vagyis a fordított, inverz forgatásra van szükségünk. Egy 3x3-as forgató mátrix inverze a mátrix transzponáltjával egyenlő. Vagyis a 4x4-es transzformációs mátrixunk felső 3x3-as forgató részmátrixának soraiba kell beírnunk a kamera X, Y és Z tengelyek normalizált irányvektorait:

R = \left( \begin{matrix} X_x & X_y & X_z & 0 \\ Y_x & Y_y & Y_z & 0 \\ Z_x & Z_y & Z_z & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right)

A View mátrix a két mátrix szorzataként adódik:

View = R \cdot T