1 视锥
视锥把空间限制在一个6面的突面体,在这个空间的物体会被渲染,下图是一个截断的金字塔。
视图窗口大小,视角,视图距离。知道任意2个计算第三个变量。
视图窗口大小固定,调整视角(fov),视角越大,视图距离(focus length)越小。
视角固定,调整视图距离,视图距离越大,视图窗口越大。
视锥通常有一个近平面,近平面距离一般不为0,因为之后做除法会有问题,在投影矩阵中讲。
远平面是可选择的,一般为了提高效率会设置一个圆平面,近平面和远平面的距离决定了深度(z)的精度。
2 齐次坐标
三维空间 R 3 R^3 R3中的点**(x,y,z)可以表示齐次坐标 R P 3 RP^3 RP3的点(x,y,z,1)**
在n维空间中的点在n+1维空间中可以通过变换n维空间点的尺度,并把这个尺度放到多出来的维度上。
(
x
,
y
,
z
)
→
(
x
′
,
y
′
,
z
′
,
w
)
(x,y,z)\to(x',y',z',w)
(x,y,z)→(x′,y′,z′,w)
即从三维空间到齐次坐标乘以一个尺度w,一般情况下w=1
(
x
w
,
y
w
,
z
w
,
w
)
(xw,yw,zw,w)
(xw,yw,zw,w)
从齐次坐标到三维坐标
(
x
′
,
y
′
,
z
′
,
w
)
→
(
x
′
/
w
,
y
′
/
w
,
z
′
/
w
)
(x',y',z',w)\to(x'/w,y'/w,z'/w)
(x′,y′,z′,w)→(x′/w,y′/w,z′/w)
三维平面的点在齐次坐标系中有n个点,即不同的w,如果当w=0情况下,
(
x
′
/
w
,
y
′
/
w
,
z
′
/
w
)
(x'/w,y'/w,z'/w)
(x′/w,y′/w,z′/w)都无穷大,表示的是一个无穷远的点。通常在代码中,我们可以设置
(
x
,
y
,
z
,
0
)
(x,y,z,0)
(x,y,z,0)表示一个向量,
(
x
,
y
,
z
,
1
)
(x,y,z,1)
(x,y,z,1)表示一个顶点。
3 透视投影
假设视角(fov)为θ,我们采用和opengl一致的右手坐标系,看向-z轴,投影在yz平面上。焦距d计算如下:
tan
θ
2
=
1
d
→
d
=
cot
θ
2
\tan \frac{\theta}{2}=\frac{1}{d}\to d=\cot \frac{\theta}{2}
tan2θ=d1→d=cot2θ
在规格化设备坐标(normalized device coordinates,ndc)中,即
x
∈
[
−
1
,
1
]
,
y
∈
[
−
1
,
1
]
x\in[-1,1],y\in[-1,1]
x∈[−1,1],y∈[−1,1],我们投影在ndc坐标系中,投影yz平面如上,
y
v
,
z
v
y_v,z_v
yv,zv表示在View空间的点,
(
y
n
d
c
,
−
d
)
(y_{ndc},-d)
(yndc,−d)表示
y
v
,
z
v
y_v,z_v
yv,zv投影在
z
=
−
d
z=-d
z=−d平面上的点,
y
n
d
c
y
v
=
d
−
z
v
→
y
n
d
c
=
d
−
z
v
y
v
\frac{y_{ndc}}{y_v}=\frac{d}{-z_v}\to y_{ndc}=\frac{d}{-z_v}y_v
yvyndc=−zvd→yndc=−zvdyv
假设平面宽高比为
a
=
w
v
h
v
a={w_v\over h_v}
a=hvwv,
w
v
,
h
v
w_v,h_v
wv,hv分别代表视窗的长和宽。同样要使得
y
v
y_v
yv归一化到
[
−
1
,
1
]
[-1,1]
[−1,1]
同理可以得到:
x
n
d
c
x
v
a
=
d
−
z
v
→
x
n
d
c
=
d
−
a
z
v
x
v
\frac{x_{ndc}}{x_v\over a}=\frac{d}{-z_v}\to x_{ndc}=\frac{d}{-az_v} x_v
axvxndc=−zvd→xndc=−azvdxv
即:
{
x
n
d
c
=
d
−
a
z
v
x
v
y
n
d
c
=
d
−
z
v
y
v
\left\{ \begin{array}{ll} x_{ndc}=\frac{d}{-az_v} x_v\\ y_{ndc}=\frac{d}{-z_v}y_v \end{array} \right.
{xndc=−azvdxvyndc=−zvdyv
总的公式如下:
{
x
n
d
c
=
d
−
a
z
v
x
v
y
n
d
c
=
d
−
z
v
y
v
z
n
d
c
=
−
d
\left\{ \begin{array}{ll} x_{ndc}=\frac{d}{-az_v} x_v\\ y_{ndc}=\frac{d}{-z_v}y_v\\ z_{ndc}=-d \end{array} \right.
⎩⎨⎧xndc=−azvdxvyndc=−zvdyvzndc=−d
所有的z坐标都变成了-d。不能表示成一个
线性或者是仿射变换。
齐次坐标中,
R
P
3
RP^3
RP3到
R
3
R^3
R3变换通过一个w量。
把w设为-zv,就可以处理这个非线性的变换。
{
x
齐
次
=
d
a
x
v
(
d
/
a
,
0
,
0
,
0
)
y
齐
次
=
d
y
v
(
0
,
d
,
0
,
0
)
z
齐
次
=
d
z
v
(
0
,
0
,
d
,
0
)
w
=
−
z
v
(
0
,
0
,
−
1
,
0
)
\left\{ \begin{array}{ll} x_{齐次}=\frac{d}{a} x_v\qquad (d/a,0,0,0)\\ y_{齐次}=dy_v\qquad (0,d,0,0)\\ z_{齐次}=dz_v\qquad (0,0,d,0)\\ w = -z_v\qquad (0,0,-1,0) \end{array} \right.
⎩⎪⎪⎨⎪⎪⎧x齐次=adxv(d/a,0,0,0)y齐次=dyv(0,d,0,0)z齐次=dzv(0,0,d,0)w=−zv(0,0,−1,0)
w未使用
写成矩阵形式
[
x
齐
次
y
齐
次
z
齐
次
w
]
=
[
d
a
0
0
0
0
d
0
0
0
0
d
0
0
0
−
1
0
]
[
x
v
y
v
z
v
1
]
\left[ \begin{array}{c} x_{齐次}\\ y_{齐次}\\ z_{齐次}\\ w \end{array} \right]= \begin{bmatrix} \frac{d}{a} & 0 & 0 & 0\\ 0 & d & 0 & 0\\ 0 & 0 & d & 0 \\ 0 & 0 & -1 & 0 \end{bmatrix} \begin{bmatrix} x_v\\ y_v\\ z_v\\ 1 \end{bmatrix}
⎣⎢⎢⎡x齐次y齐次z齐次w⎦⎥⎥⎤=⎣⎢⎢⎡ad0000d0000d−10000⎦⎥⎥⎤⎣⎢⎢⎡xvyvzv1⎦⎥⎥⎤
我们引入了一个w来表示这个变换,对于第三行我们知道把齐次坐标转换到三维坐标经过除法w。保留
z
z
z的值用于深度测试。假设缩放到[-1,1](direx3D缩放到[0,1])。
假设近平面n和远平面f。那么z的坐标值分别为-n,-f。 [-n,-f]映射到[-1,1]
同样我们采用一个尺度A和平移B变换来表示
[
x
齐
次
y
齐
次
z
齐
次
w
]
=
[
d
a
0
0
0
0
d
0
0
0
0
A
B
0
0
−
1
0
]
[
x
v
y
v
z
v
1
]
\left[ \begin{array}{c} x_{齐次}\\ y_{齐次}\\ z_{齐次}\\ w \end{array} \right]= \begin{bmatrix} \frac{d}{a} & 0 & 0 & 0\\ 0 & d & 0 & 0\\ 0 & 0 & A & B \\ 0 & 0 & -1 & 0 \end{bmatrix} \begin{bmatrix} x_v\\ y_v\\ z_v\\ 1 \end{bmatrix}
⎣⎢⎢⎡x齐次y齐次z齐次w⎦⎥⎥⎤=⎣⎢⎢⎡ad0000d0000A−100B0⎦⎥⎥⎤⎣⎢⎢⎡xvyvzv1⎦⎥⎥⎤
即
z
n
d
c
=
A
z
v
+
B
w
=
−
A
−
B
z
v
\left.z_{ndc}=\dfrac{Az_v+B}{w}=-A-\frac{B}{z_v}\right.
zndc=wAzv+B=−A−zvB
把(-n,-1),(-f,1)带入得到
A
=
n
+
f
n
−
f
B
=
2
n
f
n
−
f
A=\dfrac{n+f}{n-f}\\ B=\dfrac{2nf}{n-f}
A=n−fn+fB=n−f2nf
把AB带入公式得到:
M
p
e
r
s
p
e
c
i
t
v
e
=
[
d
a
0
0
0
0
d
0
0
0
0
n
+
f
n
−
f
2
n
f
n
−
f
0
0
−
1
0
]
M_{perspecitve}= \begin{bmatrix} \frac{d}{a} & 0 & 0 & 0\\ 0 & d & 0 & 0\\ 0 & 0 & \dfrac{n+f}{n-f} & \dfrac{2nf}{n-f} \\ 0 & 0 & -1 & 0 \end{bmatrix}
Mperspecitve=⎣⎢⎢⎢⎡ad0000d0000n−fn+f−100n−f2nf0⎦⎥⎥⎥⎤
z映射到[0,1]
M
p
e
r
s
p
e
c
i
t
v
e
=
[
d
a
0
0
0
0
d
0
0
0
0
f
n
−
f
n
f
n
−
f
0
0
−
1
0
]
M_{perspecitve}= \begin{bmatrix} \frac{d}{a} & 0 & 0 & 0\\ 0 & d & 0 & 0\\ 0 & 0 & \dfrac{f}{n-f} & \dfrac{nf}{n-f} \\ 0 & 0 & -1 & 0 \end{bmatrix}
Mperspecitve=⎣⎢⎢⎢⎡ad0000d0000n−ff−100n−fnf0⎦⎥⎥⎥⎤