### The Camera

```Navigating and viewing
the virtual world



Camera properties and definition
Perspective transformation
Quaternion transforms for changing camera

pinhole camera model
◦ tiny aperture
◦ finite size screen
Light strikes screen
Light from world
aperture

Recall that we used 3 matrices for
transformation in the BasicEffect:
◦ world (for where the object is in the virtual world)
◦ viewing (describes transformation of world to
canonical space in front of camera)
◦ projection (transform from 3D world to 2D screen)

Separation allows us to deal with each
independently



operation to transform 3D world coordinates
to 2D screen coordinates
orthogonal projection: parallel rays
perspective projection: rays pass through
aperture (pinhole, human eye)

Simple projection:
◦ (x,y,z,1)  (x,y)

z value used in depth buffer


only map objects within "canonical" viewing
volume
If the world is bigger (and not properly
oriented) need coordinate transform to map
into canonical volume




Previously, assumed the camera was axisaligned
Not typically the case!
Specify camera position, orientation
Common mechanism:
◦ camera position
◦ viewing direction
◦ up direction


Given gaze direction g, up direction h
"Camera axes": say u, v, w
◦ w = -g/|g| (gaze direction is –z)
◦ u=hxw/|hxw|
◦ v=wxu
Orthographic
Perspective
In classical perspective, have vanishing points
Parallel lines appear to converge


Orthographic projection works when we have
a large aperture
Our experience of the world is in perspective:
distant objects look smaller
aperture
small object
Objects have same
apparent size
large
object
"frustum": a truncated cone
or pyramid
near plane
z=n
far plane
z=f
ys = yg (n/zg)
ys = yr (n/zr)
ys
aperture
n
zg
yr
yg
zr
ys = yr (n/zr)



Need to divide by z
No division with matrices
Again use homogeneous coordinates:
"homogenize" operation
hx
x
y
equiv
hy
z
hz
1
h
for any nonzero h
1
0
0
0
0
1
0
0
0
0
(n+f)/n
-f
0
0
1/n
0
n
0
0
0
0
n
0
0
0
0
n+f
-fn
0
0
1
0
n
0
0
0
x
0
n
0
0
y
0
0
0
0
n+f -fn
1
0
nx
=
ny
z
(n+f)z-fn
1
z
n
0
0
0
x
0
n
0
0
y
0
0
0
0
n+f -fn
1
0
z
1
nx
=
homogenize
ny
nx/z
(n+f)z-fn
ny/z
z
(n+f)fn/z
1
n
0
0
0
x
0
n
0
0
y
0
0
0
0
n+f -fn
1
0
compare:
z
1
nx
=
homogenize
ny
nx/z
(n+f)z-fn
ny/z
z
(n+f)fn/z
ys = yg (n/zg)
1





We need to preserve Z ordering so that depth
tests still work
The perspective matrix preserves Z
At z=f, preserves z=f
At z=n, preserves z=n
At intermediate values, preserves order



Wide-angle perspective looks weird
Human focal region has small solid angle –
we do not experience severe perspective
distortion
Technically correct results may not be
perceptually correct

Recall that to specify camera position and
orientation, need 6 quantities:
◦ 3 for 3D position
◦ “ forward direction” (unit axis, 2 scalars to specify)
◦ “up direction” (orthogonal to forward, can be
specified just with an angle, one scalar)

This info goes into the viewing transform

Matrix.CreateLookAt(
cameraPosition, // where the camera is
targetPosition, // where camera looks
at
upVector // “up” direction (towards top)
);

Can apply transformations to viewing matrix
◦ translations, rotations…

Can also recreate matrix at each frame
◦ inexpensive compared to everything else!

Need to track camera orientation and position
◦ vector for position
◦ quaternion for orientation

contains:
◦ position (vector)
◦ forward direction (vector)
◦ up direction (vector)

Want to be able to swing the camera
sideways, up and down, spin (roll), plus move

Change position according to current velocity
◦ x(t+dt) = x(t) + v(t)dt


Might have v(t) from player control, or
velocity of body being followed
Might have specific camera dynamics

Often interpret player controls in terms of
◦
◦
◦
◦
move forward
move backward
strafe right, left
change orientation (right, left, up, down, roll, all in
current frame of reference)

With forward and up known as part of
camera, can change position easily
◦ move forward: x(t+dt) = x(t) + f(t)*s*dt
 s = speed, f(t) = forward direction at time t
◦ can get sideways vector as u x f (cross product)
◦ moving sideways uses same principle as moving
forward, just direction differs


Store orientation as quaternion q
Update forward, up directions using current q
◦ rotation of initial forward f0, initial up u0

say p = (0,f0), q’ = conjugate of q
◦ for q = (s,v), q' = (s,-v)

f = vector(qpq’)

In XNA, f = Vector.Transform(f0, q)


Now, changing camera orientation is easy:
Rotations about current forward, up, side
axes
◦ available, or obtained from cross product

Quaternion.CreateFromAxisAngle(axis,
angle);
◦ describes rotation

Compose with current quaternion:
◦ q = Quaternion.Multiply(q,qrot);

Normalize q, and voila!
```