视频&图片来源:【B站】GAMES101-现代计算机图形学入门-闫令琪
目录
1. 三维变换
1.1 仿射变换
齐次坐标下的仿射变换:
(
x
′
y
′
z
′
1
)
=
(
a
b
c
t
x
d
e
f
t
y
g
h
i
t
z
0
0
0
1
)
⋅
(
x
y
z
1
)
\left(\begin{matrix}x^{'}\\y^{'}\\z^{'}\\1\end{matrix}\right)=\left(\begin{matrix}a&b&c&t_x\\d&e&f&t_y\\g&h&i&t_z\\0&0&0&1\end{matrix}\right)\cdot\left(\begin{matrix}x\\y\\z\\1\end{matrix}\right)
⎝⎜⎜⎛x′y′z′1⎠⎟⎟⎞=⎝⎜⎜⎛adg0beh0cfi0txtytz1⎠⎟⎟⎞⋅⎝⎜⎜⎛xyz1⎠⎟⎟⎞
先线性变换,再平移:
- 缩放矩阵: S ( s x , s y , s z ) = ( s x 0 0 0 0 s y 0 0 0 0 s z 0 0 0 0 1 ) S(s_x,s_y,s_z)=\left(\begin{matrix}s_x&0&0&0\\0&s_y&0&0\\0&0&s_z&0\\0&0&0&1\end{matrix}\right) S(sx,sy,sz)=⎝⎜⎜⎛sx0000sy0000sz00001⎠⎟⎟⎞
- 平移矩阵: T ( t x , t y , t z ) = ( 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ) T(t_x,t_y,t_z)=\left(\begin{matrix}1&0&0&t_x\\0&1&0&t_y\\0&0&1&t_z\\0&0&0&1\end{matrix}\right) T(tx,ty,tz)=⎝⎜⎜⎛100001000010txtytz1⎠⎟⎟⎞
- 绕轴旋转:
沿X轴: R x ( α ) = ( 1 0 0 0 0 cos α − sin α 0 0 sin α cos α 0 0 0 0 1 ) R_x(\alpha)=\left(\begin{matrix}1&0&0&0\\0&\cos\alpha&-\sin\alpha&0\\0&\sin\alpha&\cos\alpha&0\\0&0&0&1\end{matrix}\right) Rx(α)=⎝⎜⎜⎛10000cosαsinα00−sinαcosα00001⎠⎟⎟⎞
沿Y轴: R y ( α ) = ( cos α 0 sin α 0 0 1 0 0 − sin α 0 cos α 0 0 0 0 1 ) R_y(\alpha)=\left(\begin{matrix}\cos\alpha&0&\sin\alpha&0\\0&1&0&0\\-\sin\alpha&0&\cos\alpha&0\\0&0&0&1\end{matrix}\right) Ry(α)=⎝⎜⎜⎛cosα0−sinα00100sinα0cosα00001⎠⎟⎟⎞ 循环对称性
沿Z轴: R z ( α ) = ( cos α − sin α 0 0 sin α cos α 0 0 0 0 1 0 0 0 0 1 ) R_z(\alpha)=\left(\begin{matrix}\cos\alpha&-\sin\alpha&0&0\\\sin\alpha&\cos\alpha&0&0\\0&0&1&0\\0&0&0&1\end{matrix}\right) Rz(α)=⎝⎜⎜⎛cosαsinα00−sinαcosα0000100001⎠⎟⎟⎞
1.2 任意的旋转
3D下任意的旋转,都可以分解成绕X轴、绕Y轴、绕Z轴的旋转。
即:
R
x
y
z
(
α
,
β
,
γ
)
=
R
x
(
α
)
R
y
(
β
)
R
z
(
γ
)
R_{xyz}(\alpha,\beta,\gamma)=R_x(\alpha)R_y(\beta)R_z(\gamma)
Rxyz(α,β,γ)=Rx(α)Ry(β)Rz(γ),其中
α
,
β
,
γ
\alpha,\beta,\gamma
α,β,γ称为欧拉角
-
罗德里格斯旋转公式:绕轴n旋转 α \alpha α度
R ( n , α ) = cos ( α ) I + ( 1 − cos ( α ) ) n n T + sin ( α ) ( 0 − n z n y n z 0 − n x − n y n x 0 ) R(n,\alpha)=\cos(\alpha)I+(1-\cos(\alpha))nn^T+\sin(\alpha)\left(\begin{matrix}0&-n_z&n_y\\n_z&0&-n_x\\-n_y&n_x&0\end{matrix}\right) R(n,α)=cos(α)I+(1−cos(α))nnT+sin(α)⎝⎛0nz−ny−nz0nxny−nx0⎠⎞
这里的轴n默认过原点,否则会出现方向上的问题 -
推广:如果绕任意点/任意轴旋转,基本思路是把这个点平移到原点/使轴过原点,旋转完再平移回之前的位置
2. 观测变换 Viewing transformation
一个引入例子:拍照
- 找一堆人来拍👉模型变换(Model)
- 找一个拍照角度,改变相机位置👉视图变换(View)
- 拍照!👉投影变换(Projection)
2.1 视图(View)/ 相机变换
如何确定相机的位置:
- 放置相机的位置: e → \overrightarrow{e} e
- 视线方向,朝哪看(Look-at/gaze direction): g ^ \hat{g} g^
- 朝向上的方向: t ^ \hat{t} t^
一个特性:当相机和物体之间保持相对静止,即相机和被拍摄物之间的位置关系不发生改变,则移动相机或被拍摄物,拍摄结果也不会发生改变。
基于该特性,一般默认:相机永远固定在原点位置上,看向
−
Z
-Z
−Z轴方向,以
Y
Y
Y轴为向上方向。
从上图到下图的基本思想:
- e → \overrightarrow{e} e作平移,移动到原点
- g ^ \hat{g} g^移动到 − Z -Z −Z方向上
- t ^ \hat{t} t^旋转到 Y Y Y方向上
- g ^ × t ^ \hat{g}\times\hat{t} g^×t^得到的向量旋转到 X X X方向上
用矩阵形式表示:
M
v
i
e
w
=
R
v
i
e
w
T
v
i
e
w
M_{view}=R_{view}T_{view}
Mview=RviewTview,
T
v
i
e
w
=
[
1
0
0
−
x
e
0
1
0
−
y
e
0
0
1
−
z
e
0
0
0
1
]
T_{view}=\left[\begin{matrix}1&0&0&-x_e\\0&1&0&-y_e\\0&0&1&-z_e\\0&0&0&1\end{matrix}\right]
Tview=⎣⎢⎢⎡100001000010−xe−ye−ze1⎦⎥⎥⎤
关于
R
v
i
e
w
R_{view}
Rview,直接求不好求,可以用
R
v
i
e
w
−
1
R_{view}^{-1}
Rview−1(逆变换,相当于世界坐标系变为相机的坐标系)求:
R
v
i
e
w
−
1
=
[
x
g
^
×
t
^
x
t
x
−
g
0
y
g
^
×
t
^
y
t
y
−
g
0
z
g
^
×
t
^
z
t
z
−
g
0
0
0
0
1
]
⇒
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}^{-1}=\left[\begin{matrix}x_{\hat{g}\times\hat{t}}&x_t&x_{-g}&0\\y_{\hat{g}\times\hat{t}}&y_t&y_{-g}&0\\z_{\hat{g}\times\hat{t}}&z_t&z_{-g}&0\\0&0&0&1\end{matrix}\right]\Rightarrow R_{view}=\left[\begin{matrix}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{matrix}\right]
Rview−1=⎣⎢⎢⎡xg^×t^yg^×t^zg^×t^0xtytzt0x−gy−gz−g00001⎦⎥⎥⎤⇒Rview=⎣⎢⎢⎡xg^×t^xtx−g0yg^×t^yty−g0zg^×t^ztz−g00001⎦⎥⎥⎤
2.2 投影变换
2.2.1 正交投影
一个简单的正交投影做法:
- 相机放在原点,看向 − Z -Z −Z方向,向上为 Y Y Y方向(通用的摆放方式)
- 扔掉 Z Z Z的坐标,只剩下 X 和 Y X和Y X和Y得到的结果直接是平面上的图像
- 不管原始的
x
和
y
x和y
x和y有多大,经过平移和缩放,使图像落在
[
−
1
,
1
]
2
[-1,1]^2
[−1,1]2的范围内(约定俗成的做法)
图形学上的变化方法: - 定义空间中的立方体,左右在 X X X轴作用,下上在 Y Y Y轴上作用,远近在 Z Z Z轴上作用(Z值近大远小)
- 把该立方体映射到标准立方体
[
−
1
,
1
]
3
[-1,1]^3
[−1,1]3上(先平移再缩放)
矩阵形式:
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 ] M_{ortho}=\left[\begin{matrix}\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{matrix}\right]\left[\begin{matrix}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{matrix}\right] Mortho=⎣⎢⎢⎡r−l20000t−b20000n−f200001⎦⎥⎥⎤⎣⎢⎢⎡100001000010−2r+l−2t+b−2n+f1⎦⎥⎥⎤
注: n − n e a r ; f − f a r ; t − t o p ; b − b o t t o m ; l − l e f t ; r − r i g h t n-near; f-far; t-top; b-bottom; l-left; r-right n−near;f−far;t−top;b−bottom;l−left;r−right
再注:完成投影变换后,无论原始物体的长宽比如何,经过缩放后长宽比会发生改变,精度也可能有问题,后续还有其他处理。
2.2.2 透视投影
带来的一个结果:平行线不再平行(指透视延伸)
齐次坐标的性质: ( x , y , z , 1 ) ; ( k x , k y , k z , k ) , k ≠ 0 ; ( x z , y z , z 2 , z ) , z ≠ 0 (x,y,z,1);(kx,ky,kz,k),k\not=0;(xz,yz,z^2,z),z\not=0 (x,y,z,1);(kx,ky,kz,k),k=0;(xz,yz,z2,z),z=0,表示的都是同一个点 ( x , y , z ) (x,y,z) (x,y,z)。
规定:
- 近平面永远不变(四个点固定,平面上的任何一个点同理)
- 远平面 Z Z Z值/轴 不变(平面向内收缩)
- 远平面中心点不变
思考:远平面向内压缩时,平面上的点的深度值如何变大?(点往近了跑还是往远了跑?)
- 盲猜变远…压缩会把多出来的点压到靠后的位置…