Developedia
Developedia
A virtuális kamera látótere

A virtuális kamera látótere

Vízszintes / függőleges látótér

Korábban láthattuk, hogy mind perspektív, mind pedig ortografikus kamera egy transzformált téglatestet vág ki a térből:

  • Ortografikus kamera: Téglatest
  • Perspektív kamera: Frusztum (Csapott tetejű piramis)

A különböző kameratípusokról bővebben: Virtuális kamerákVirtuális kamerák

Hogy ez test a a kamera pozíciójához képest hol kezdődik és a milyen távol fejeződik be azt az elülső és hátulsó vágósík (vágó-távolság) határozta meg, a látótér mérete egy szám alapján volt állítható.

  • Ortografikus kamera: Kamera által belátott magasság (Ortographic Size)
  • Perspektív kamera: Kamera függőleges látószöge (Field of View)

Figyeljük meg, hogy mindkét esetben ezen értékek függőlegesek. Nincs arra lehetőség, hogy vízszintes szélességet és látószöget állítsunk egy kamerán. Ezen vízszintes értékeket mindig a megfelelő függőleges adatokból valamint a képernyő képarányából számolja ki a Unity.

(Hogy ezt miért nem lehet könnyedén szabályozni az jó kérdés… Főleg úgy hogy a perspektív esetben olyan mintha, lehetne. Ám ez senkit ne tévesszen meg. Próbáljátok csak meg beállítani a vízszintes Field of View-et majt méretezzétek át a Game ablakot. Egyből látjátok, hogy valójában ugyanúgy a függőleges látószög a fix.)

Azonban ne aggódjunk, könnyedén tudunk egy egyszerű saját szkriptet írni erre a célra.

Ehhez a Camera.aspect lekérdezést használhatjuk fel, ami a képarányt adja meg.

Ortographic:

[SerializeField] float orthographicSize;
[SerializeField, Range(0, 1)] float useHorizontalSize;

// ...

float verticalSize = orthographicSize / Mathf.Lerp(1, camera.aspect, useHorizontalSize);
controlledCamera.orthographicSize = verticalSize;

Perspektív:

[SerializeField] float fieldOfView;
[SerializeField, Range(0, 1)] float useHorizontalFOV;

// ...

float verticalFOV = fieldOfView / Mathf.Lerp(1, camera.aspect, useHorizontalFOV);
camera.fieldOfView = verticalFOV;

Kamera nyílásszöge (Field of view), a célpont mérete és a távolságuk

Korábban láttuk, hogyan tudunk egy kamerát egy célpontra irányítani úgy, hogy a kettejük közti távolságot valamint a kamerának vízszintes és függőleges dőlésszögét adjuk meg beállításként:

Célpontkövető kameraCélpontkövető kamera

Ha belegondolunk azonban, akkor a felhasználó / game designer számára általában nem az fontos, hogy milyen távol van a kamera a céltól, sokkal inkább az, hogy a célpont mekkorában látszik a képernyőn. Ez ortografikus kamera esetén egyszerűen beállítható az Ortographic Size segítségével, a kérdés perspektív kamera esetén trükkösebb, így a továbbiakban csak ezzel az esetett foglalkozunk.

3 egymással szorosan összefüggő paramétert vehetünk fel egy perspektív kameránál.

  • ddd: targetDistance: A target objektum, azaz célpont és a kamera távolsága.
  • α\alphaα: camera.fieldOfView: a kamera függőleges nyílásszöge.
  • sss: targetScale: A belátott terület magassága a célpontban.

A három érték közül bármely kettőt tudjuk, akkor a harmadik kiszámolható a többiből.

Felrajzólhatunk a fenti adatokból egy derékszögű háromszöget (bár itt-ott osztani kell kettővel). Derékszögű háromszög esetén pedig tudjuk, hogy Pitagorasz tétel és a trigonometriai függvények segíthetnek kiszámolni a nem ismert változókat.

image

Mivel ezúttal egy szög és a befogók kapcsolatát akarjuk felvázolni a tangens függvény lesz segítségünkre, ugyanis:

Szög tangens-e: Szöggel szemközti és a szög melletti befogó hányadosa.

Tehát a következő összefüggés írható le:

tg(α/2)=s/2dtg (\alpha / 2) =\frac{s/2}{d}tg(α/2)=ds/2​

Ezt az képletet átalakíthatjuk, úgy hogy a fenti paraméterek közül bármely kettőt kiválasztva megkapjuk a harmadikat:

d=s2⋅tg(α/2)d = \frac{s}{2 ⋅ tg (\alpha / 2)}d=2⋅tg(α/2)s​
s=d⋅tg(α/2)2s = \frac{d ⋅ tg (\alpha / 2)}{2}s=2d⋅tg(α/2)​
α=2⋅arctan(s/2d)\alpha =2 ⋅ arctan( \frac{s / 2}{d})α=2⋅arctan(ds/2​)

Most eldönthetjük, hogy a programunkban melyik kettő paraméter lesz egy beállítás és melyik lesz az, amelyiket származtatjuk a másik kettőből.

Nálam a targetDistance lesz a származtatott:

A fentiek egybevonhatók a következő szkripttel: Célpontkövető kameraCélpontkövető kamera

Az eredmény: Olyan mint egy dolly-zoom
icon
Dolly-zoom

A Dolly-zoom egy filmes kamera effekt, amit Alfred Hitchcock dolgozott ki Irmin Roberts operatőrrel a Szédülés című mára klasszikussá vált filmhez. (Korábban is kísérletezett az effekttel kevesebb sikerrel) Az effekt lényege, hogy úgy változtatja az operatőr a kamera zoom-ot, hogy közben a célpont és a kamera távolsága is módosul. A gyakorlatban egy sínen (dolly-n) mozog a kamera a cél felé.

Ezen effekttel megoldható, hogy a célobjektum mérete ne változzon, mégis drasztikusan átalakuljon a kép. Ezáltal kényelmetlen, idegen hatást kelthet a filmkészítő.

Szédülés - Vertigo (1958)
Szédülés - Vertigo (1958)
Cápa - Jaws (1975)
Cápa - Jaws (1975)
A gyűrű szövetsége - The Fellowship of the Ring (2001)
A gyűrű szövetsége - The Fellowship of the Ring (2001)
Nagymenők - Goodfellas (1990)
Nagymenők - Goodfellas (1990)
Logo

Főoldal

Blog

Elmélet

3D Studio

Adatvédelmi nyilatkozat

GY.I.K.

Házirend

Szerző: Marosi Csaba / marosi.csaba@3d-studio.hu

DiscordGitHubLinkedIn

[SerializeField] Camera controlledCamera;
[SerializeField] Transform target;

[SerializeField] float targetScale = 1;    // A célpont mérete
[SerializeField] float fieldOfView = 30f;  // Kamera nyílásszöge

void Update()
{
	if(target == null) return;
	if(controlledCamera == null) return;
	        
	controlledCamera.fieldOfView = fieldOfView;
	float fieldOfViewRad = fieldOfView * Mathf.Deg2Rad;
	float targetDistance = targetSize / (2 * Mathf.Tan(fieldOfViewRad / 2f));

  // ... Camera pozíciójának beállítása távolság alapján: Korábbi leckében
}