文章为学习《Unity Shader入门精要》冯乐乐著时做的笔记
笛卡尔坐标系
1. 二维笛卡尔坐标系
其实我们小学就开始接触的二维坐标系就是笛卡尔坐标系,只是我们当时并不知道这个名字而已。
x轴和y轴互相垂直,也称为该坐标系的基矢量。
在OpenGL和DirectX中使用了不同的二维笛卡尔坐标系
2. 三维笛卡尔坐标系
三维笛卡尔坐标系中,需要定义三个坐标轴和一个原点,如下图:
这三个坐标轴也称为基矢量(basis vector),通常三个坐标轴是互相垂直的,而且长度为1,这样的基矢量称为标准正交基。假如长度不为1,这样的基矢量称为正交基。
3. 左手坐标系、右手坐标系
笛卡尔三维坐标系又分为左手坐标系和右手坐标系
4. Unity使用的坐标系
-
在模型空间和世界空间中,Unity使用的是左手坐标系
-
对于观察空间来说,Unity使用的是右手坐标系。
观察空间,就是摄像机为原点的坐标系,此坐标系中,摄像机前向是z轴的负方向,也就是说,z轴坐标减少,场景深度增加。
矢量
1. 矢量与点
点(point)是n维空间中的一个位置,没有大小与宽度。
矢量(vector,也称向量),是指在n维空间一种包含模和方向的有向线段。
- 矢量的模,指的是矢量的长度,是一个任意非负数
- 矢量的方法,指描述了这个矢量在空间中的指向
表示方法:
- 二维矢量:v = (x, y)
- 三维矢量: v = (x, y, z)
- 四维矢量: v = (x, y, z, w)
2. 矢量计算
-
矢量与标量的乘除法
乘法:只需要把矢量的每个分量都与标量相乘。
k v = ( k v x , k v y , k v z ) kv = (kv_x, kv_y, kv_z) kv=(kvx,kvy,kvz)
除法:等同于和这个标量的倒数相乘
v k = ( x , y , z ) k = 1 k ( x , y , z ) = ( x k , y k , z k ) , k ≠ 0 \frac vk = \frac {(x,y,z)}k = \frac 1k (x,y,z) = \left( \frac xk, \frac yk, \frac zk \right), k\neq 0 kv=k(x,y,z)=k1(x,y,z)=(kx,ky,kz),k=0 -
矢量加减法
两矢量进行相加减,结果为一个相同维度的新矢量。计算过程中只需要两矢量的相应分量进行相加减即可:
a + b = ( a x + b x , a y + b y , a z + b z ) a+b = (a_x+b_x,a_y+b_y,a_z+b_z) a+b=(ax+bx,ay+by,az+bz)
**注意:**矢量不可以跟标量相加减,或者和不同维度的矢量进行运算。
3. 矢量的模
矢量的模式一个标量,可理解为矢量在空间中的长度。三维矢量的模计算公式如下:
∣
v
∣
=
v
x
2
+
v
y
2
+
v
z
2
|v| = \sqrt{v_x^2+v_y^2+v_z^2}
∣v∣=vx2+vy2+vz2
其他维度的模计算类似,都是对每个分量平方后相加再开根号。
4. 单位矢量
单位矢量指模为1的矢量,也称为被归一化的矢量,非零矢量转为单位矢量的过程称为归一化。
矢量归一化公式:
v
^
=
v
∣
v
∣
\hat v = \frac v{|v|}
v^=∣v∣v
零矢量:每个分量都是0,如v = (0,0,0),零矢量是不可以被归一化的。
5. 矢量的点积
矢量的乘法有两种常用的种类:
- 点积,也称内积
- 叉积,也称外积
两矢量的点积是把矢量对应分量相乘后再取和,最终得到一个标量。
公式一:
a
⋅
b
=
(
a
x
,
a
y
,
a
z
)
⋅
(
b
x
,
b
y
,
b
z
)
=
a
x
b
x
+
a
x
b
y
+
a
z
b
z
a \cdot b = (a_x,a_y,a_z) \cdot (b_x,b_y,b_z) = a_xb_x+a_xb_y+a_zb_z
a⋅b=(ax,ay,az)⋅(bx,by,bz)=axbx+axby+azbz
点积的几何意义:投影(projection)
点积的性质:
-
性质1:点积可结合标量乘法 ( k a ) ⋅ b = a ⋅ ( k b ) = k ( a ⋅ b ) (ka)·b = a \cdot (kb) = k(a \cdot b) (ka)⋅b=a⋅(kb)=k(a⋅b)
也就是说点积对一个矢量进行缩放,相当于对最后的结果进行缩放
-
性质2:点积可结合矢量加法和减法
a ⋅ ( b + c ) = a ⋅ b + a ⋅ c a \cdot (b+c) = a \cdot b + a\cdot c a⋅(b+c)=a⋅b+a⋅c -
性质3:一个矢量和自身进行点积的结果,是该矢量的模的平方
v ⋅ v = ∣ v ∣ 2 v\cdot v = |v|^2 v⋅v=∣v∣2
6. 矢量的叉积
矢量的叉积的结果仍然是一个矢量。叉积公式如下:
a
×
b
=
(
a
x
,
a
y
,
a
z
)
×
(
b
x
,
b
y
,
b
z
)
=
(
a
y
b
z
−
a
z
b
y
,
a
z
b
x
−
a
x
b
z
,
a
x
b
y
−
a
y
b
x
)
a \times b = (a_x,a_y,a_z) \times (b_x,b_y,b_z) = (a_yb_z-a_zb_y,a_zb_x-a_xb_z,a_xb_y-a_yb_x)
a×b=(ax,ay,az)×(bx,by,bz)=(aybz−azby,azbx−axbz,axby−aybx)
叉积不满足交换律,即$ a \times b \neq b\times a$,但是实际上
a
×
b
=
−
(
b
×
a
)
a \times b = - (b\times a)
a×b=−(b×a)
叉积不满足结合律,即 ( a × b ) × c ≠ a × ( b × c ) (a \times b)\times c \neq a \times (b \times c) (a×b)×c=a×(b×c)
几何意义:对两个矢量进行叉积的结果会得到一个同时垂直于这两个矢量的新矢量。
应用:计算一个垂直于一个平面、三角形的矢量。
矩阵
1. 矩阵运算
1.1 矩阵和标量的乘法
k M = M k = k [ m 11 m 12 m 13 m 21 m 22 m 23 m 31 m 32 m 33 ] = [ k m 11 k m 12 k m 13 k m 21 k m 22 k m 23 k m 31 k m 32 k m 33 ] kM = Mk = k \left[ \begin{matrix} m_{11}&m_{12}&m_{13}\\ m_{21}&m_{22}&m_{23}\\ m_{31}&m_{32}&m_{33}\\ \end{matrix} \right] = \left[ \begin{matrix} km_{11}&km_{12}&km_{13}\\ km_{21}&km_{22}&km_{23}\\ km_{31}&km_{32}&km_{33}\\ \end{matrix} \right] kM=Mk=k⎣⎡m11m21m31m12m22m32m13m23m33⎦⎤=⎣⎡km11km21km31km12km22km32km13km23km33⎦⎤
1.2 矩阵和矩阵的乘法
两矩阵的乘法结果是一个新的矩阵,维度跟两个矩阵维度相关。
矩阵A为r x n的矩阵,矩阵B为n x c的矩阵。AB将是r x c大小的矩阵。
注意:第一个矩阵的列数必须等于第二个矩阵的行数,结果为第一个矩阵的行数,第二个矩阵的列数
矩阵A跟矩阵B相乘,结果得到矩阵C,C中的每个元素
c
i
j
c_{ij}
cij,由A中的第i行和B中的第j列,相乘后相加,即:
c
i
j
=
a
i
1
b
1
j
+
a
i
2
b
2
j
+
.
.
.
+
a
i
n
b
n
j
=
∑
k
=
1
n
a
i
k
b
k
j
c_{ij} = a_{i1}b_{1j}+a_{i2}b_{2j}+ ... + a_{in}b_{nj} = \sum_{k=1}^n a_{ik}b_{kj}
cij=ai1b1j+ai2b2j+...+ainbnj=k=1∑naikbkj
例如:
A
=
[
a
11
a
12
a
21
a
22
a
31
a
32
]
A= \left[ \begin{matrix} a_{11}&a_{12}\\ a_{21}&a_{22}\\ a_{31}&a_{32}\\ \end{matrix} \right]
A=⎣⎡a11a21a31a12a22a32⎦⎤
$$
B = \left[ \begin{matrix}
b_{11}&b_{12}&b_{13}&b_{14}\
b_{21}&b_{22}&b_{23}&b_{24}\
\end{matrix} \right]
$$
相乘结果C:
C
=
[
c
11
c
12
c
13
c
14
c
21
c
22
c
23
c
24
c
31
c
32
c
33
c
34
]
C = \left[ \begin{matrix} c_{11}&c_{12}&c_{13}&c_{14}\\ c_{21}&c_{22}&c_{23}&c_{24}\\ c_{31}&c_{32}&c_{33}&c_{34}\\ \end{matrix} \right]
C=⎣⎡c11c21c31c12c22c32c13c23c33c14c24c34⎦⎤
则
c
23
=
a
21
b
13
+
a
22
b
23
c_{23} = a_{21}b_{13}+a_{22}b_{23}
c23=a21b13+a22b23
矩阵乘法性质:
-
性质一:不满足交换律,即 A B ≠ B A AB \neq BA AB=BA
-
性质二:满足结合律,即 ( A B ) C = A ( B C ) (AB)C = A(BC) (AB)C=A(BC)
2. 特殊矩阵
在Shader中经常见到的特殊矩阵,这些矩阵往往具有一些重要的性质。
2.1 方块矩阵
简称方阵,指行数和列数相等的矩阵。三维渲染中最常见的就是 3 × 3 3 \times 3 3×3和 4 × 4 4 \times 4 4×4的方阵。
角元素:行号跟列号相等的元素,如 m 11 m_{11} m11, m 22 m_{22} m22等。因为这些元素排在正方形的对角线上,故而称为角元素。
对角矩阵:除了角元素外的所有元素都是0,这样的矩阵称为对角矩阵。如:
[
1
0
0
0
0
2
0
0
0
0
3
0
0
0
0
4
]
\left[ \begin{matrix} 1&0&0&0\\ 0&2&0&0\\ 0&0&3&0\\ 0&0&0&4\\ \end{matrix} \right]
⎣⎢⎢⎡1000020000300004⎦⎥⎥⎤
2.2 单位矩阵
对角元素都为1的对角矩阵,称为单位矩阵(identity matrix),用
I
n
I_n
In来表示,如:
[
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
]
\left[ \begin{matrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{matrix} \right]
⎣⎢⎢⎡1000010000100001⎦⎥⎥⎤
与单位矩阵相乘的矩阵,结果还是原来的矩阵,这就是单位矩阵名字的由来。即:
M
I
=
I
M
=
M
MI = IM = M
MI=IM=M
2.3 转置矩阵
转置矩阵其实是对原矩阵的一种运算,即转置运算。例如
r
×
c
r \times c
r×c的矩阵M,它的转置矩阵为
M
T
M^T
MT,
M
T
M^T
MT为一个
c
×
r
c \times r
c×r的矩阵。
M
i
j
T
=
M
j
i
M_{ij}^T = M_{ji}
MijT=Mji
例如:
[
1
2
3
4
5
6
7
8
]
T
=
[
1
5
2
6
3
7
4
8
]
\left[ \begin{matrix} 1&2&3&4\\ 5&6&7&8\\ \end{matrix} \right]^T = \left[ \begin{matrix} 1&5\\ 2&6\\ 3&7\\ 4&8\\ \end{matrix} \right]
[15263748]T=⎣⎢⎢⎡12345678⎦⎥⎥⎤
转置矩阵性质:
-
性质一:矩阵转置的转置等于原矩阵,即
( M T ) T = M (M^T)^T = M (MT)T=M -
矩阵串接的转置,等于反向串接各个矩阵的转置。
( A B ) T = B T A T (AB)^T = B^TA^T (AB)T=BTAT
2.4 逆矩阵
逆矩阵是一种特俗的方阵,它的特殊之处在于原矩阵和其逆矩阵相乘,结果为一个单位矩阵,例如矩阵M,其逆矩阵未
M
−
1
M^{-1}
M−1
M
M
−
1
=
M
−
1
M
=
I
MM^{-1} = M^{-1}M = I
MM−1=M−1M=I
不是所有方阵都有对应的逆矩阵,例如元素都为0的矩阵就不存在逆矩阵(因为相乘都为0)。
矩阵有对应逆矩阵,我们称该矩阵是可逆的,或者非奇异的,没有逆矩阵的则称为不可逆的,或者奇异的。
逆矩阵性质:
-
性质一:逆矩阵的逆矩阵还是原来的矩阵本身
( M − 1 ) − 1 = M (M^{-1})^{-1} = M (M−1)−1=M -
性质二:单位矩阵的逆矩阵是它本身。
I − 1 = I I^{-1} = I I−1=I -
性质三:转置矩阵的逆矩阵是逆矩阵的转置
( M T ) − 1 = ( M − 1 ) T (M^T)^{-1} = (M^{-1})^T (MT)−1=(M−1)T -
性质四:矩阵串接相乘后的逆矩阵等于反向串接各个矩阵的逆矩阵。
( A B ) − 1 = B − 1 A − 1 (AB)^{-1} = B^{-1}A^{-1} (AB)−1=B−1A−1
2.5 正交矩阵
正交是矩阵的一种属性,如果一个方阵M和它的转置矩阵的成绩是单位矩阵的话,则称这个矩阵是正交的,即
M
M
T
=
M
T
M
=
I
MM^T = M^TM = I
MMT=MTM=I
这个式子跟逆矩阵公式:
M
M
−
1
=
M
−
1
M
=
I
MM^{-1} = M^{-1}M = I
MM−1=M−1M=I 很相似,两个公式结合就能得到一个重要的性质,即如果一个矩阵是正交的,那么他的转置矩阵和逆矩阵是一样的。也就是说
M
T
=
M
−
1
M^T = M^{-1}
MT=M−1
矩阵的几何意义:变换
1. 变换
变换(transform),指把数据通过某种方式进行转换的过程,这些数据可以是点、方向甚至颜色等。
线性变换:那些可以保留矢量加和标量乘的变换。
f
(
x
)
+
f
(
y
)
=
f
(
x
+
y
)
f(x)+f(y) = f(x+y)
f(x)+f(y)=f(x+y)
k f ( x ) = f ( k x ) kf(x) = f(kx) kf(x)=f(kx)
常见的线性变换:缩放(scale)、旋转(rotation)、错切(shear)、镜像(morroring,也称reflection)、正交投影(orthographic projection)
2. 齐次坐标
齐次坐标就是把n维向量,用n+1维向量表示。齐次坐标只是为了方便计算的一种表示方式而已。
例如:3*3矩阵不能表示平移操作,拓展到4*4就能实现。
如何将三维矢量变成四维矢量?
- 对于一个点,只需要把其w分量设为1;
- 对于方向矢量来说,需要把其w分量设为0;
这样操作后,用4*4的矩阵对一个点进行变换时,平移、旋转、缩放都会施加于该点
对一个方向矢量进行变换时,将不起作用。
3. 分解基础变换矩阵
4*4的矩阵能表示平移、旋转和缩放。我们把表示纯平移、纯旋转和纯缩放的变换叫做基础变换矩阵。基础变换矩阵分解如下:
[
M
3
×
3
t
3
×
1
0
1
×
3
1
]
\left[ \begin{matrix} M_{3\times3}&t_{3\times1}\\ 0_{1\times3}&1 \end{matrix} \right]
[M3×301×3t3×11]
- M 3 × 3 M_{3\times 3} M3×3用于表示旋转和缩放
- t 3 ∗ 3 t_{3*3} t3∗3用于表示平移
- $0_{1*3} = \left[
\begin{matrix}
0&0&0\
\end{matrix}
\right] $ - 右下角是标量1
4. 平移矩阵
-
我们可以用矩阵乘法来对一个点(x,y,z)进行平移变换:
该点齐次坐标为(x,y,z,1)
[ 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ] [ x y z 1 ] = [ x + t x y + t y z + t z 1 ] \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] \left[ \begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix} \right]= \left[ \begin{matrix} x+t_x\\ y+t_y\\ z+t_z\\ 1\\ \end{matrix} \right] ⎣⎢⎢⎡100001000010txtytz1⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡x+txy+tyz+tz1⎦⎥⎥⎤
从几何上看,就是把点 ( x , y , z ) (x,y,z) (x,y,z)在空间中移动了 ( t x , t y , t z ) (t_x,t_y,t_z) (tx,ty,tz)个单位。
-
对一个方向矢量(x,y,z)进行平移变换,结果如下:
该矢量的齐次坐标为(x,y,z,0)
[ 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ] [ x y z 0 ] = [ x y z 0 ] \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] \left[ \begin{matrix} x\\ y\\ z\\ 0\\ \end{matrix} \right]= \left[ \begin{matrix} x\\ y\\ z\\ 0\\ \end{matrix} \right] ⎣⎢⎢⎡100001000010txtytz1⎦⎥⎥⎤⎣⎢⎢⎡xyz0⎦⎥⎥⎤=⎣⎢⎢⎡xyz0⎦⎥⎥⎤
可以发现,平移变换不会对方向矢量产生任何影响。
构建平移矩阵:
基础变换矩阵中的 t 3 × 1 t_{3\times 1} t3×1矢量对应了平移矢量,左上角的矩阵 M 3 × 3 M_{3\times 3} M3×3为单位矩阵 I 3 I_3 I3。
平移矩阵的逆矩阵就是方向平移得到的矩阵,即
[
1
0
0
−
t
x
0
1
0
−
t
y
0
0
1
−
t
z
0
0
0
1
]
\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]
⎣⎢⎢⎡100001000010−tx−ty−tz1⎦⎥⎥⎤
可以看出,平移矩阵并不是一个正交矩阵。
5. 缩放矩阵
我们可以对一个模型沿空间的x轴、y轴、z轴进行缩放。矩阵乘法表示如下:
[
k
x
0
0
0
0
k
y
0
0
0
0
k
z
0
0
0
0
1
]
[
x
y
z
1
]
=
[
k
x
x
k
y
y
k
z
z
1
]
\left[ \begin{matrix} k_x&0&0&0\\ 0&k_y&0&0\\ 0&0&k_z&0\\ 0&0&0&1\\ \end{matrix} \right] \left[ \begin{matrix} x\\ y\\ z\\ 1\\ \end{matrix} \right]= \left[ \begin{matrix} k_xx\\ k_yy\\ k_zz\\ 1\\ \end{matrix} \right]
⎣⎢⎢⎡kx0000ky0000kz00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡kxxkyykzz1⎦⎥⎥⎤
对反向矢量进行同样的矩阵进行缩放:
[
k
x
0
0
0
0
k
y
0
0
0
0
k
z
0
0
0
0
1
]
[
x
y
z
0
]
=
[
k
x
x
k
y
y
k
z
z
0
]
\left[ \begin{matrix} k_x&0&0&0\\ 0&k_y&0&0\\ 0&0&k_z&0\\ 0&0&0&1\\ \end{matrix} \right] \left[ \begin{matrix} x\\ y\\ z\\ 0\\ \end{matrix} \right]= \left[ \begin{matrix} k_xx\\ k_yy\\ k_zz\\ 0\\ \end{matrix} \right]
⎣⎢⎢⎡kx0000ky0000kz00001⎦⎥⎥⎤⎣⎢⎢⎡xyz0⎦⎥⎥⎤=⎣⎢⎢⎡kxxkyykzz0⎦⎥⎥⎤
统一缩放:缩放系数
k
x
=
k
y
=
k
z
k_x = k_y = k_z
kx=ky=kz,其余都是非统一缩放。
缩放矩阵的逆矩阵是使用原缩放系数的倒数来对点或方向矢量进行缩放,即
[
1
k
x
0
0
0
0
1
k
y
0
0
0
0
1
k
z
0
0
0
0
1
]
\left[ \begin{matrix} \frac{1}{k_x}&0&0&0\\ 0&\frac{1}{k_y}&0&0\\ 0&0&\frac{1}{k_z}&0\\ 0&0&0&1\\ \end{matrix} \right]
⎣⎢⎢⎡kx10000ky10000kz100001⎦⎥⎥⎤
缩放矩阵一般不是正交矩阵。
6. 旋转矩阵
- 把点绕x轴旋转
θ
\theta
θ度,可以使用下面矩阵:
R x ( θ ) = [ 1 0 0 0 0 cos θ − sin θ 0 0 sin θ cos θ 0 0 0 0 1 ] R_x(\theta)=\left[ \begin{matrix} 1&0&0&0\\ 0&\cos\theta&-\sin\theta&0\\ 0&\sin\theta&\cos\theta&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(\theta)=\left[ \begin{matrix} \cos\theta&0&\sin\theta&0\\ 0&1&0&0\\ -\sin\theta&0&\cos\theta&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(\theta)=\left[ \begin{matrix} \cos\theta&-\sin\theta&0&0\\ \sin\theta&\cos\theta&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{matrix} \right] Rz(θ)=⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎤
旋转矩阵的逆矩阵是旋转相反角度得到的变换矩阵。
旋转矩阵是正交矩阵,多个旋转矩阵之间的串联同样是正交的。
7. 复合变换
可以将平移、旋转和缩放进行组合,形成一个复杂的变换过程。例如,可以对模型先缩放(2,2,2),再绕y轴旋转
3
0
。
30^。
30。,最后向z轴平移4个单位。符合变换可以通过矩阵串联来实现:
P
n
e
w
=
M
t
r
a
n
s
l
a
t
i
o
n
M
r
o
t
a
t
i
o
n
M
s
c
a
l
e
P
o
l
d
(
阅
读
顺
序
从
右
往
左
)
P_{new} = M_{translation}M_{rotation}M_{scale}P_{old}(阅读顺序从右往左)
Pnew=MtranslationMrotationMscalePold(阅读顺序从右往左)
变换的结果依赖于变换的顺序,矩阵乘法不满足交换律,因此不同的乘法顺序得到的结果不相同。
约定顺序:先缩放,再旋转,最后平移
坐标空间
1. 坐标空间的变换
每个空间都有一个父(parent)坐标空间,对坐标空间的变换实际上就是在父空间和子空间对点和矢量进行转换。
已头晕@@@,之后再补!!!
2. 模型空间
模型空间(model spacce),有时也称对象空间,或者局部空间,每个模型都有自己独立的坐标空间。
Unity在模型空间中使用左手坐标系,在此模型空间中,+x轴、+y轴、+z轴分别对应模型的右、上和前向。
3. 世界空间
世界空间(word space)是一个特殊的坐标系,它创建了我们所关心的最大的空间。这里的最大指的是我们所关心的最外层的坐标空间。
4. 观察空间
观察空间(view space),也被称为摄像机空间(camera space)。观察空间可以认为是模型空间的一个特例。
Unity中观察空间的坐标轴选择:+x轴指向右方,+y轴指向上方,+z轴指向的是摄像机的后方。
Unity中观察空间使用的是右手坐标系,在这样的空间中,摄像机的正前方指向的是-z轴的方向。
注意:观察空间和屏幕空间不同,观察空间是三维空间,屏幕空间是二维空间。之间的转换需要进行投影。
顶点变换的第二步,是将顶点坐标从世界空间变换到观察空间中,这个变换叫观察变换。
5. 裁剪空间
裁剪空间(clip space, 也称为齐次裁剪空间),用于变换的矩阵叫裁剪矩阵,也称投影矩阵。
裁剪空间的目标是能够方便地对渲染图元进行裁剪:
- 完全在这空间内部的图元完全保留。
- 完全在这空间外部的图元完全剔除。
- 与这块空间相交的图元就会被裁剪。
判断一个顶点是否位于视锥体内部,可以通过投影矩阵把顶点转换到一个裁剪空间中。
以上指的空间由视锥体来决定。视锥体指空间中一块区域,这块区域来决定摄像机所能看到的空间。
视锥体由六个平面包围而成,这些平面称为裁剪平面。如下所示:
投影类型:
- 正交投影,完全保留物体的距离和角度
- 透视投影,模拟人眼看世界的方式,近大远小
6.屏幕空间
使用投影矩阵变换后,我们进行了裁剪操作,接下来就需要进行真正的投影。即把视锥体投影到屏幕空间(screen space)。经过这一步,就得到真正的像素位置,而不是虚拟的三维坐标。
屏幕空间是二维的空间,故而我们要把顶点从裁剪空间投影到屏幕空间中,来生成对应的2D坐标:
1.首先进行标准的齐次除法,也称为透视除法,操作很简单,只需要用齐次坐标系中的w分量去除以x,y,z分量。
OpenGL中,这一步得到的坐标称为归一化设备坐标(Normalized Device Coordinates,NDC)。
经过投影变换后的裁剪空间,再经过齐次除法后会变换到一个立方体内。
- 按OpenGL传统,这个立方体的x,y,z分量的范围都是[-1,1]。Unity选择OpenGL这样的齐次裁剪空间。
- 在DirectX这样的API中,z分量的范围会是[0,1]。
对于正交投影来说,它的裁剪空间实际已经是一个立方体了,而且经过正交投影矩阵变换后的顶底的w分量是1,因此经过齐次除法不会对x,y,z坐标产生影响。如图所示:
2.经过齐次除法后,透视投影和正交投影的视锥体都变换到一个相同的立方体内,接下来就可以根据变换后的x和y坐标来映射输出窗口的对应像素坐标。
变换后,我们进行了裁剪操作,接下来就需要进行真正的投影。即把视锥体投影到屏幕空间(screen space)。经过这一步,就得到真正的像素位置,而不是虚拟的三维坐标。
屏幕空间是二维的空间,故而我们要把顶点从裁剪空间投影到屏幕空间中,来生成对应的2D坐标:
1.首先进行标准的齐次除法,也称为透视除法,操作很简单,只需要用齐次坐标系中的w分量去除以x,y,z分量。
OpenGL中,这一步得到的坐标称为归一化设备坐标(Normalized Device Coordinates,NDC)。
经过投影变换后的裁剪空间,再经过齐次除法后会变换到一个立方体内。
- 按OpenGL传统,这个立方体的x,y,z分量的范围都是[-1,1]。Unity选择OpenGL这样的齐次裁剪空间。
- 在DirectX这样的API中,z分量的范围会是[0,1]。
[外链图片转存中…(img-Mwc7cSTb-1585294378238)]
对于正交投影来说,它的裁剪空间实际已经是一个立方体了,而且经过正交投影矩阵变换后的顶底的w分量是1,因此经过齐次除法不会对x,y,z坐标产生影响。如图所示:
[外链图片转存中…(img-Ukre7YIh-1585294378239)]
2.经过齐次除法后,透视投影和正交投影的视锥体都变换到一个相同的立方体内,接下来就可以根据变换后的x和y坐标来映射输出窗口的对应像素坐标。