MVP变换
MVP变换用来描述视图变换的任务,即将虚拟世界中的三维物体映射(变换)到二维坐标中。
MVP变换分为三步:
- 模型变换(model tranformation):将模型空间转换到世界空间(找个好的地方,把所有人集合在一起,摆个pose)
- 摄像机变换(view tranformation):将世界空间转换到观察空间(找到一个放相机的位置,往某一个角度去看)
- 投影变换(projection tranformation):将观察空间转换到裁剪空间(茄子!)
在这之后,还有一个#视口变换
视图变换(View)
视图变换的目的是变换Camera位置到原点,上方为Y,观察方向为-Z,即
M
v
i
e
w
=
R
v
i
e
w
T
v
i
e
w
=
[
x
g
^
×
t
^
y
g
^
×
t
^
z
g
^
×
t
^
0
x
t
y
t
z
t
0
x
−
g
y
g
z
−
g
0
0
0
0
1
]
[
1
0
0
−
x
e
0
1
0
−
y
c
0
0
1
−
z
c
0
0
0
1
]
\begin{align} M_{view}&=R_{view}T_{view}\\ &=\begin{bmatrix} x_{\hat{g}\times\hat{t}}& y_{\hat{g}\times\hat{t}}& z_{\hat{g}\times\hat{t}}& 0\\ x_{t}& y_{t}& z_{t}& 0\\ x_{-g}& y_{g}& z_{-g}& 0\\ 0& 0& 0& 1 \end{bmatrix} \begin{bmatrix}1& 0& 0& -x_{e}\\ 0& 1& 0& -y_{c}\\ 0& 0& 1& -z_{c}\\ 0& 0& 0& 1\end{bmatrix} \end{align}
Mview=RviewTview=
xg^×t^xtx−g0yg^×t^ytyg0zg^×t^ztz−g00001
100001000010−xe−yc−zc1
定义Camera:
- Camera位置 e ⃗ \vec{e} e
- 观察方向 g ^ \hat{g} g^
- 视点上方向 t ^ \hat{t} t^
规定:
- Camera的y轴正方向向上,z轴方向是 − x ⃗ × y ⃗ -\vec{x}\times \vec{y} −x×y(右手系)
- 对物体进行运动,摄像机会跟随着一起运动保持相对位置不变。
变换Camera位置到原点,上方为Y,观察方向为-Z:
- 把 e ⃗ \vec{e} e移动到标准位置: T v i e w = [ 1 0 0 − x e 0 1 0 − y c 0 0 1 − z c 0 0 0 1 ] T_{view}=\begin{bmatrix}1& 0& 0& -x_{e}\\ 0& 1& 0& -y_{c}\\ 0& 0& 1& -z_{c}\\ 0& 0& 0& 1\end{bmatrix} Tview= 100001000010−xe−yc−zc1 (因为朝原点移动,所以为负)
- 旋转 g ^ \hat{g} g^到-Z , t ⃗ \vec{t} t到Y, g ^ × t ⃗ \hat{g}\times\vec{t} g^×t到X: R v i e w = [ x g ^ × t ^ y g ^ × t ^ z g ^ × t ^ 0 x t y t z t 0 x − g y g z − g 0 0 0 0 1 ] R_{view}=\begin{bmatrix}x_{\hat{g}\times\hat{t}}& y_{\hat{g}\times\hat{t}}& z_{\hat{g}\times\hat{t}}& 0\\ x_{t}& y_{t}& z_{t}& 0\\x_{-g}& y_{g}& z_{-g}& 0\\ 0& 0& 0& 1\end{bmatrix} Rview= xg^×t^xtx−g0yg^×t^ytyg0zg^×t^ztz−g00001
推导:这个过程是旋转X到 g ^ × t ^ \hat{g}\times\hat{t} g^×t^,Y到 t ^ \hat{t} t^,Z到 − g ^ -\hat{g} −g^的逆过程。所以 R v i e w R_{view} Rview是这个逆过程的逆矩阵(正交矩阵的逆是转置矩阵):
模型变换和视图变换经常被一起叫作模型视图变换(ModelView Translation)
投影变换(Projection)
投影变换分为两种:
- 正交投影变换:透视线平行
- 透视投影变换:透视线相交,近大远小
正交投影
M o r t h o = [ 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ] [ 1 0 0 − r + L 2 0 1 0 − t + b 2 0 0 1 − n + f 2 0 0 0 1 ] = [ 2 r − l 0 0 − r + l r − l 0 2 t − b 0 − t + b t − b 0 0 2 n − f − n + f n − f 0 0 0 1 ] \begin{align} M_{ortho}&=\begin{bmatrix}\frac{2}{r-l}& 0& 0& 0\\ 0& \frac{2}{t-b}& 0& 0\\ 0& 0& \frac{2}{n-f}& 0\\ 0& 0& 0& 1\end{bmatrix} \begin{bmatrix}1& 0& 0& -\frac{r+L}{2}\\ 0& 1& 0& -\frac{t+b}{2}\\ 0& 0& 1& -\frac{n+f}{2}\\ 0& 0& 0& 1\end{bmatrix}\\\\ &=\begin{bmatrix}\frac{2}{r-l}& 0& 0& -\frac{r+l}{r-l}\\ 0& \frac{2}{t-b}& 0& -\frac{t+b}{t-b}\\ 0& 0& \frac{2}{n-f}& -\frac{n+f}{n-f}\\ 0& 0& 0& 1\end{bmatrix} \end{align} Mortho= r−l20000t−b20000n−f200001 100001000010−2r+L−2t+b−2n+f1 = r−l20000t−b20000n−f20−r−lr+l−t−bt+b−n−fn+f1
正交投影的核心:用一个立方体框住物体的 [ l , r ] × [ b , t ] × [ f , n ] [l,r]\times[b,t]\times[f,n] [l,r]×[b,t]×[f,n],把这个立方体变换到标准正方体 [ − 1 , 1 ] 3 [-1,1]^{3} [−1,1]3中。
变换顺序:先移动(中点移动到原点),再缩放(基向量缩放比例为
2
长
/
宽
/
高
\frac{2}{长/宽/高}
长/宽/高2 )。
注意事项:
- 右手系:n>f
- OpenGl是左手系
透视投影
M p e r = M o r t h o M p e r s p → − o r t h o = [ 2 r − l 0 0 − r + l r − l 0 2 t − b 0 − t + b t − b 0 0 2 n − f − n + f n − f 0 0 0 1 ] [ n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ] = [ 2 n r − l 0 l + r l − r 0 0 2 n t − b b + t b − t 0 0 0 f + n n − f 2 f n f − n 0 0 1 0 ] \begin{align} M_{per}&=M_{ortho}M_{persp\rightarrow -ortho}\\\\ &=\begin{bmatrix}\frac{2}{r-l}& 0& 0& -\frac{r+l}{r-l}\\ 0& \frac{2}{t-b}& 0& -\frac{t+b}{t-b}\\ 0& 0& \frac{2}{n-f}& -\frac{n+f}{n-f}\\ 0& 0& 0& 1\end{bmatrix}\begin{bmatrix}n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& n+f& -nf\\ 0& 0& 1& 0\end{bmatrix}\\\\ &=\begin{bmatrix}\frac{2n}{r-l}& 0&\frac{l+r}{l-r}& 0\\ 0& \frac{2n}{t-b}& \frac{b+t}{b-t}& 0\\ 0& 0& \frac{f+n}{n-f}& \frac{2fn}{f-n}\\ 0& 0& 1& 0\end{bmatrix} \end{align} Mper=MorthoMpersp→−ortho= r−l20000t−b20000n−f20−r−lr+l−t−bt+b−n−fn+f1 n0000n0000n+f100−nf0 = r−l2n0000t−b2n00l−rl+rb−tb+tn−ff+n100f−n2fn0
透视投影的核心:用“远平面”和“近平面”框住物体,先把“远平面”向“近平面“挤压,然后做一次正交投影。
即透视投影分为两步:
- 将透视投影转化为正交投影
- 将正交投影转换到正则立方体
研究挤压:
规定:
- 挤压过程中,近平面和远平面的z值不发生变换(中间要发生变化)
- 挤压过程中,远平面中心原点 ( x , y ) T (x,y)^{T} (x,y)T不发生变化
挤压过程中的x,y变化的比例关系:
x同理。
y
′
=
n
z
y
,
x
′
=
n
z
x
y' = \frac{n}{z}y,~~x'=\frac{n}{z}x
y′=zny, x′=znx
用齐次坐标描述任一点的坐标变换:
[
x
y
z
1
]
→
[
n
x
/
z
n
y
/
z
u
n
k
n
o
w
n
1
]
=
[
n
x
n
y
z
⋅
u
n
k
o
w
n
z
]
\begin{align} \begin{bmatrix}x\\ y\\ z\\ 1\end{bmatrix}\rightarrow \begin{bmatrix} nx/z\\ ny/z\\ unknown\\ 1\end{bmatrix}=\begin{bmatrix}nx\\ ny\\ z\cdot unkown\\ z\end{bmatrix} \end{align}
xyz1
→
nx/zny/zunknown1
=
nxnyz⋅unkownz
把这个变换用齐次坐标矩阵表示:
M
(
4
×
4
)
[
x
y
z
1
]
=
=
[
n
x
n
y
z
⋅
u
n
k
o
w
n
z
]
M(4\times 4)\begin{bmatrix}x\\ y\\ z\\ 1\end{bmatrix}==\begin{bmatrix}nx\\ ny\\ z\cdot unkown\\ z\end{bmatrix}
M(4×4)
xyz1
==
nxnyz⋅unkownz
根据矩阵乘法,可以写出M的大致形式:
M
=
[
n
0
0
0
0
n
0
0
?
?
?
?
0
0
1
0
]
M=\begin{bmatrix}n& 0& 0& 0\\ 0& n& 0& 0\\ ?& ?& ?& ?\\ 0& 0& 1& 0\end{bmatrix}
M=
n0?00n?000?100?0
代入上面提到的两种点:
- 近平面或远平面上的任一点(令 u n k n o w n = n , z = n unknown=n,z=n unknown=n,z=n): M [ x y n 1 ] = [ n x n y n 2 n ] M\begin{bmatrix}x\\ y\\ n\\ 1\end{bmatrix}=\begin{bmatrix}nx\\ ny\\ n^{2}\\ n\end{bmatrix} M xyn1 = nxnyn2n 根据矩阵乘法行操作: M 第三行 [ x y n 1 ] = n 2 M第三行\begin{bmatrix}x\\ y\\ n\\ 1\end{bmatrix}=n^{2} M第三行 xyn1 =n2 因为不涉及旋转,所以第三行与x,y无关。 [ 0 0 A B ] [ x y n 1 ] = n 2 \begin{bmatrix}0& 0& A& B\end{bmatrix}\begin{bmatrix}x\\ y\\ n \\ 1\end{bmatrix}=n^{2} [00AB] xyn1 =n2 即: A n + B = n 2 An+B=n^{2} An+B=n2
- 远平面的原点(令 x = 0 , y = 0 , z = f x=0,y=0,z=f x=0,y=0,z=f): [ 0 0 f 1 ] → [ 0 0 f 2 f ] \begin{bmatrix}0\\ 0\\ f\\ 1\end{bmatrix} \rightarrow \begin{bmatrix}0\\ 0\\ f^{2}\\ f\end{bmatrix} 00f1 → 00f2f 同理可得: A f + B = f 2 Af+B=f^{2} Af+B=f2
综上所述,
A
=
n
+
f
B
=
−
n
f
A=n+f B=-nf
A=n+fB=−nf
求得变换矩阵为:
M
p
e
r
s
p
→
−
o
r
t
h
o
=
[
n
0
0
0
0
n
0
0
0
0
n
+
f
−
n
f
0
0
1
0
]
M_{persp\rightarrow -ortho}=\begin{bmatrix}n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& n+f& -nf\\ 0& 0& 1& 0\end{bmatrix}
Mpersp→−ortho=
n0000n0000n+f100−nf0
得到透视投影矩阵为:
M
p
e
r
=
M
o
r
t
h
o
M
p
e
r
s
p
→
−
o
r
t
h
o
=
[
2
r
−
l
0
0
−
r
+
l
r
−
l
0
2
t
−
b
0
−
t
+
b
t
−
b
0
0
2
n
−
f
−
n
+
f
n
−
f
0
0
0
1
]
[
n
0
0
0
0
n
0
0
0
0
n
+
f
−
n
f
0
0
1
0
]
=
[
2
n
r
−
l
0
l
+
r
l
−
r
0
0
2
n
t
−
b
b
+
t
b
−
t
0
0
0
f
+
n
n
−
f
2
f
n
f
−
n
0
0
1
0
]
\begin{align} M_{per}&=M_{ortho}M_{persp\rightarrow -ortho}\\\\ &=\begin{bmatrix}\frac{2}{r-l}& 0& 0& -\frac{r+l}{r-l}\\ 0& \frac{2}{t-b}& 0& -\frac{t+b}{t-b}\\ 0& 0& \frac{2}{n-f}& -\frac{n+f}{n-f}\\ 0& 0& 0& 1\end{bmatrix}\begin{bmatrix}n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& n+f& -nf\\ 0& 0& 1& 0\end{bmatrix}\\\\ &=\begin{bmatrix}\frac{2n}{r-l}& 0&\frac{l+r}{l-r}& 0\\ 0& \frac{2n}{t-b}& \frac{b+t}{b-t}& 0\\ 0& 0& \frac{f+n}{n-f}& \frac{2fn}{f-n}\\ 0& 0& 1& 0\end{bmatrix} \end{align}
Mper=MorthoMpersp→−ortho=
r−l20000t−b20000n−f20−r−lr+l−t−bt+b−n−fn+f1
n0000n0000n+f100−nf0
=
r−l2n0000t−b2n00l−rl+rb−tb+tn−ff+n100f−n2fn0
视口变换
视口变换
将处于标准平面映射到屏幕分辨率范围之内,即[-1,1]^2->[0,width]*[0,height], 其中width和height指屏幕分辨率大小
视锥
视锥表示看起来像顶部切割后平行于底部的金字塔的实体形状。这是透视摄像机可以看到和渲染的区域的形状。
定义视锥:
- 长宽比 Aspect
- 垂直的角度 FovY
利用视锥得到物体长宽高:
屏幕(Screen)
- 二维数组,数组元素为像素
- 典型的光栅成像设备
光栅(Raster)
- 德语中的屏幕
- 画在屏幕上
像素(Pixel <- PIcture element)
- 像素是一个颜色均匀的小正方形
- 颜色混合而成(红、绿、蓝)
屏幕空间
认为屏幕左下角是原点,向右是x,向上是y
规定:
- 像素坐标(Pixel’s indices)是(x, y)形式,x, y都是整数。
- 所有的像素都在(0, 0)到(width-1, height-1)之间
- 像素的中心:(x+0.5, y+0.5)
- 整个屏幕覆盖(0,0)to(width,height)
视口变换
要做的事情:
先不考虑z轴,把MVP后处于标准立方体
[
−
1
,
1
]
3
[-1,1]^{3}
[−1,1]3映射到屏幕上。即
[
−
1
,
1
]
2
→
[
0
,
w
i
d
t
h
]
×
[
0
,
h
e
i
g
h
t
]
[-1, 1]^{2}\rightarrow [0,width]\times [0,height]
[−1,1]2→[0,width]×[0,height]
总结:把虚拟世界的任意可视物体转换到屏幕:
M
=
M
v
i
e
w
M
p
e
r
M
c
a
m
M
m
o
d
e
l
M=M_{view}M_{per}M_{cam}M_{model}
M=MviewMperMcamMmodel