CS580
Building and Using Transformations
Ulrich Neumann
CS580
Computer Graphics Rendering
Building the matrices (Xsp)
Xsp matrix scales NDC to output device (FB size)
NDC is a used as a fixed rendering-target space (LH coords)
NDC is display-device and window-size independent
Perspective (NDC) space has a [-1, 1] visible range for (x,y) and origin at screen center
Square aspect-ratio for screen size and pixels (our definitions)
Screen coords are RH coords with origin in upper left
Map entire NDC visible range to screen with a scale and translation
Do a “best-fit” to NDC when Display FB is not square
Xsp = T S Where:
T shifts the origin and
S scales the NDC screen size to the FB size
Xsp = xs/2 0 0 xs/2
0 -ys/2 0 ys/2
0 0 1 0
0 0 0 1
Building the matrices (Xsp)
Recall that NDC space is defined to have a bounded
z-range : z ϵ [0, 1]
Integer Z-buffer resolution has a fixed range [0-MAXINT] and we should scale “z” to use all of it
Scale NDC “z” by MAXINT
put MAXINT in Xsp[2][2] to scale screen-space
z-range : z ϵ [0, MAXINT]
Try it at extreme corners of NDC space …
?? = Xsp [0,0,0,1]
?? = Xsp [1,1,0,1]
?? = Xsp [0,0,1,1]
?? = Xsp [-1,1,0,1]
….
You could set up 12 eq’s like these to solve for top 3 rows of matrix terms.
It’s much easier to build it as a T S transformation that meets our definitions of screen space and perspective space.
Note that Xsp has non-uniform scaling. This is one of the special cases where such a transformation occurs.
Xsp = xs/2 0 0 xs/2
0 -ys/2 0 ys/2
0 0 MAXINT 0
0 0 0 1
Building the matrices (Xpi)
Xpi matrix takes image space to perspective space
Image space has no bounds on X,Y, or Z
Perspective space (NDC) has the same origin and axis, but there is a singularity for points with Z = -d (due to perspective divide)
clip or cull all triangles with any vertex Z<0
The projection term in Xpi is defined by the distance “d” from the view plane to focal point (also FOV)
Points that project to visible-range of NDC space will be “on screen”
Points that project outside of visible-range should NOT appear in FB
d
FOV
+1
-1
1/d=tan(FOV/2)
Xpi = 1 0 0 0
0 1 0 0
0 0 1 0
0 0 1/d 1
Building the matrices (Xpi)
Recall that perspective-z is bounded z ϵ [0,d] by the perspective transform
We defined NDC z-range to be : z ϵ [0,1] so we need to scale z by 1/d
Put 1/d into Xpi[2][2]
Final Xpi maps all visible points into NDC bounded range
Note that Xpi has non-uniform scaling.
Xsp and Xpi are both special cases where such transformations are used.
Xpi = 1 0 0 0
0 1 0 0
0 0 1/d 0
0 0 1/d 1
Building the matrices (Xiw)
Xiw Camera matrix puts world coordinates into image-space (camera space) where they are relative to the camera and ready for projection
Choose a world coord position for the camera (view plane origin) = c
Choose a world coord “look-at” point = l
Compute camera Z-axis, Z = cl / || cl || (normalized world-space vector)
When camera z-axis is know, only one more constraint is needed to fully define the camera orientation
Choose an up vector (any world-space vector) to constrain the camera’s spin-orientation about its z-axis
Construct the camera Y-axis to lie in the plane created by the camera Z-axis and the up vector
The Z-axis and up vector directions can not be the same
Pick (0, 1, 0) as the up vector
in world space (for our example)
Note that up vector need not be
normalized so we could also
use (3, 100, -20), for example
l
c
Z
up
Building the matrices (Xiw)
Construct : up' = up - (up Z)Z
The up’ vector is orthogonal to the camera Z-axis, by construction
up’ also lies in the plane created by the up-vector and Z-axis
So, up’ is the direction of the camera Y-axis, but we need to normalize it to use it as the camera axis : Y = up' / || up'||
The camera X-axis is orthogonal to the Y-axis and Z-axis, so we can construct it by cross-product : X = (Y x Z) (LH coords for camera)
The X axis should point “out” of the screen for the case drawn
X = (Y x Z) =
i (Yy Zz - Yz Zy) +
j (Yz Zx - Yx Zz) +
k (Yx Zy - Yy Zx)
change the “up” direction to spin
the camera about it’s Z-axis
l
c
Z
up
up’
Y
X
out
Building the matrices (Xwi)
Computed camera X, Y, Z axes are all normalized and orthogonal -- and expressed as world space coords, so we can build Xwi directly
Camera origin in world coords : [cx, cy, cz] = Xwi [0, 0, 0]T
camera origin translates to camera location in world space
right column of Xwi matrix does this translation
3x3 UR rotation has column vectors with the 3 camera axis X, Y, Z prior slides computed in world space
an input camera axis vector of [1,0,0] or [0,1,0] or [0,0,1] will output one of these columns as the world space vector for that axis
Xwi = Xx Yx Zx Cx
Xy Yy Zy Cy
Xz Yz Zz Cz
0 0 0 1
Building the matrices (Xiw)
Xiw is the inverse of Xwi, shown on prior slide
Use the decomposition : Xwi = T R
Create R-1 and T-1 and concatenate them to get Xiw = R-1 T-1
-The translation column elements become dot-products of two vectors during concatenation
The final result is shown below :
Xiw = Xx Xy Xz -XC
Yx Yy Yz -YC
Zx Zy Zz -ZC
0 0 0 1
*
Using Transformations for
Animation and Scene Setup
Place a model in the world
Model’s world position and orientation is
defined by Xwm
Push Xwm onto initialized stack with Xsw
Now stack has Xsm so render the model
If Xwm = T then model origin becomes point = T in world space
Note that the model and world axes are aligned so the model orientation in the world is determined by the world axes
If Xwm = TSR then model coords/axes are rotated about model origin, scaled in/out of model origin, and then translated with the origin moving to point T in world space
Model in Model Space
World Space
origin-axis
Xwm places model in World Space
Think of the model origin (0,0,0) and axes (1,0,0) (0,1,0) (0,0,1) transformed by Xwm to their world position and orientations
camera looking at origin, for example, is setup as part of Xsw
x
y
z
x
y
z
y
x
z
How to Instance N-Chairs
Given a chair world position T, orientation R, and size S
Xwm = T R S
Assume origin of chair model is suitable for scaling and rotation
A good “suitable” origin is a point in the middle of the leg-bottoms
Scale the chair model about its origin to the desired size
Rotate the scaled chair about its origin to the desired orientation
Translate the chair to its desired position in the world
Concatenate above transforms to create one matrix Xwm = T R S
Start with initialized Xsw on stack
Push a new Xwm on stack (stack now has Xsm )
Render the chair model
Pop to remove Xwm
repeat this 3-step sequence with new Xwm = TRS for each chair
Orbit a Model about a Point
Pushing Xwm = TSR on stack places/orients the model. R rotates the model about its origin prior to scale and translation (spinning in place)
To orbit the model about point P (rotation about Y-axis), position and orient the model to a point along the orbit path (at radius from P with same Y-coord)
Then move the origin to P and use it as a “fixed point” for the rotation about the Y-axis (P is defined in World Space)
Lastly, put the origin back to the world space axes so the model cords are in world space again for rendering
Note, the same cube face will always face P
Model in Model Space
World Space
origin-axis
P = Point in World Space
Xwm=TSR places model in World Space
The cube always faces P
x
y
z
x
y
z
Orbit a Model about a Point (2)
Application builds an Ri as a pure rotation about the Y-axis whose angle can be varied from frame to frame (to create an animation)
Orient cube in model space and place model in world with X =TSR [X]
Translate by Tp = –P to move origin from world origin to P [Tp]
Rotate by Ri about P (about Y-axis) [Ri]
Translate by P or [Tp]-1 to reset world origin [Tp]-1
Assume initial stack state = Xsw ready for model matrix
Push [Tp]-1 then [Ri] then [Tp] then [X]
Stack has: [Xsw] [Tp]-1 [Ri] [Tp] [X] ready for model rendering
Model in Model Space
World Space
origin-axis
X=TSR places model in World Space
P = Point in World Space
The cube always faces P
x
y
z
x
y
z
Orbit a Model about a Point (3)
* Follow the origin/axes in the transformations: [Xsw] [Tp-1] [Ri] [Tp] [X]
Origin Axes
[Xsw] [Tp-1] [Ri] [Tp] [X] * : Model Model (given)
[Xsw] [Tp-1] [Ri] [Tp] * [X] : World rotated World
[Xsw] [Tp-1] [Ri] * [Tp] [X] : P rotated World
[Xsw] [Tp-1] * [Ri] [Tp] [X] : P World
[Xsw] * [Tp-1] [Ri] [Tp] [X] : World World (given)
Model in Model Space
World Space
origin-axis
X=TSR places model in World Space
P = Point in World Space
The cube always faces P
x
y
z
x
y
z
Orbit a Model about a Point (4)
P
Looking down the y-axis
M
After: [X] M places/orients model in world
P
M
After: [Tp] [X] M moves origin to P
(-15,0,0) (-10,0,0) (0,0,0)
(0,0,0) (5,0,0) (15,0,0)
P
M
(0,0,0) (4.9 ,0, .85) (14.7, 0, 2.25)
After: [Ri] [Tp] [X] M rotates about P
(10 degree rotation for example)
P
M
(-15,0,0) (-10.1, 0, 0.85) (0, 0, 0)
After: [Tp]-1 [Ri] [Tp] [X] resets origin
Note: the original origin and the new origin are not the same points
x
z
W
x
z
x
z
W
x
z
x
z
W
x
z
x
z
x
z
W
Orbit a Model about a Point (5)
Other transformation sequences can be created to get a similar result
Orbit about P is also achieved by this sequence:
Use [X]=TSR to place model at desired radius from world origin : [X]
Do the incremental rotation about world origin : [R] [X]
Translate model by Tp=P to make it appear to rotate about P : [Tp] [R] [X]
Final stack transformation sequence is : [ Xsw ] [Tp] [R] [X]
Model in Model Space
World Space
origin-axis
P = Point in World Space
x
y
z
x
y
z