文章目录
概述
本文的图片来源和主要参考文献为:Fundamentals of Computer Graphics
渲染中的空间转换如下图所示:
在渲染过程中会涉及到五个空间以及四个转换.
初始空间 | 变换 | 目标空间 |
---|---|---|
模型空间(Object space) | 模型变换(Modeling transformation) | 世界空间(World space) |
世界空间(World space) | 观察变换(Camera transformation) | 观察空间 (Camera space) |
观察空间 (Camera space) | 投影变换(Projection transformation) | 裁剪空间 (Clip space) |
裁剪空间 (Clip space) | 归一化 | 归一化设备坐标(NDC) |
归一化设备坐标(NDC) | 屏幕映射(Viewport transformation) | 屏幕空间(Screen space) |
屏幕映射(Viewport transformation)
基础知识
像素坐标约定
像素值其实就是一个个的小格子,它的索引及坐标都是整数.但是我们现实中使用的坐标都为实数坐标.
像素坐标无固定的定义,这里仅作为一种约定方便讨论.
这里假设横向格子为
n
x
n_x
nx,纵向格子为
n
y
n_y
ny. 那么我们实际使用的坐标区域为:
R
=
[
−
0.5
,
n
x
−
0.5
]
×
[
−
0.5
,
n
y
−
0.5
]
R=[-0.5,n_x-0.5]\times[-0.5,n_y-0.5]
R=[−0.5,nx−0.5]×[−0.5,ny−0.5]
窗口转换
窗口转换的目标为构建一个映射,把矩形A中的点映射到矩形B中.
这里假定矩形A为
[
x
l
,
x
h
]
×
[
y
l
,
y
h
]
[x_l,x_h]\times[y_l,y_h]
[xl,xh]×[yl,yh]
矩形B为
[
x
l
′
,
x
h
′
]
×
[
y
l
′
,
y
h
′
]
[x_l',x_h']\times[y_l',y_h']
[xl′,xh′]×[yl′,yh′].
一种方法是先把A缩放到和B一样的大小,然后再通过平移让矩阵对齐.
但是由于直接缩放会让平移的参数难以获得,另一种更直观的方案如下图所示:
我们先让矩形A的左下角平移至原点,然后进行缩放使得矩形A的大小和矩阵B的大小一致.
其次我们再通过平移使得矩形A和矩形B对齐即可.
这里我们不用过多关心构建的过程,因为我们经我们组合后只会获得一个最终矩阵. 所以在构建过程中越简单越直观越好.
我们使用列向量来表示坐标,所以矩阵的应用从右手边开始. 我们矩阵如下:
窗
口
转
换
=
(
平
移
使
A
和
B
对
齐
)
(
缩
放
A
使
A
大
小
和
B
一
致
)
(
平
移
A
使
左
下
角
到
原
点
)
窗口转换=(平移使A和B对齐) (缩放A使A大小和B一致)(平移A使左下角到原点)
窗口转换=(平移使A和B对齐)(缩放A使A大小和B一致)(平移A使左下角到原点)
即:
w
i
n
d
o
w
=
t
r
a
n
s
l
a
t
e
(
x
l
′
,
y
l
′
)
  
s
c
a
l
e
(
x
h
′
−
x
l
′
x
h
−
x
l
,
y
h
′
−
y
l
′
y
h
−
y
l
)
  
t
r
a
n
s
l
a
t
e
(
−
x
l
,
−
y
l
)
window=translate(x_l',y_l') \; scale(\frac{x_h'-x_l'}{x_h-x_l},\frac{y_h'-y_l'}{y_h-y_l}) \;translate(-x_l,-y_l)
window=translate(xl′,yl′)scale(xh−xlxh′−xl′,yh−ylyh′−yl′)translate(−xl,−yl)
使用矩阵表示:
w
i
n
d
o
w
=
[
0
0
0
x
l
′
0
0
0
y
l
′
0
0
0
0
0
0
0
1
]
[
x
h
′
−
x
l
′
x
h
−
x
l
0
0
0
0
y
h
′
−
y
l
′
y
h
−
y
l
0
0
0
0
0
0
0
0
0
1
]
[
0
0
0
−
x
l
0
0
0
−
y
l
0
0
0
0
0
0
0
1
]
window= \begin{bmatrix} 0 & 0&0&x_l'\\ 0 & 0&0&y_l' \\ 0 & 0&0&0 \\ 0 & 0&0&1 \\ \end{bmatrix} \begin{bmatrix} \frac{x_h'-x_l'}{x_h-x_l} & 0&0&0 \\ 0 & \frac{y_h'-y_l'}{y_h-y_l}&0&0 \\ 0 & 0&0&0 \\ 0 & 0&0&1 \\ \end{bmatrix} \begin{bmatrix} 0 & 0&0&-x_l \\ 0 & 0&0&-y_l \\ 0 & 0&0&0 \\ 0 & 0&0&1 \\ \end{bmatrix}
window=⎣⎢⎢⎡000000000000xl′yl′01⎦⎥⎥⎤⎣⎢⎢⎢⎡xh−xlxh′−xl′0000yh−ylyh′−yl′0000000001⎦⎥⎥⎥⎤⎣⎢⎢⎡000000000000−xl−yl01⎦⎥⎥⎤
w
i
n
d
o
w
=
[
x
h
′
−
x
l
′
x
h
−
x
l
0
0
x
l
′
x
h
−
x
h
′
x
l
x
h
−
x
l
0
y
h
′
−
y
l
′
y
h
−
y
l
0
y
l
′
y
h
−
y
h
′
y
l
y
h
−
y
l
0
0
0
0
0
0
0
1
]
window = \begin{bmatrix} \frac{x_h'-x_l'}{x_h-x_l} & 0&0&\frac{x_l'x_h-x_h'x_l}{x_h-x_l} \\ 0 & \frac{y_h'-y_l'}{y_h-y_l}&0&\frac{y_l'y_h-y_h'y_l}{y_h-y_l} \\ 0 & 0&0&0 \\ 0 & 0&0&1 \\ \end{bmatrix}
window=⎣⎢⎢⎢⎡xh−xlxh′−xl′0000yh−ylyh′−yl′000000xh−xlxl′xh−xh′xlyh−ylyl′yh−yh′yl01⎦⎥⎥⎥⎤
扩展一维同理.
假设我们要把长方体
[
x
l
,
x
h
]
×
[
y
l
,
y
h
]
×
[
z
l
,
z
h
]
[x_l,x_h]\times[y_l,y_h]\times[z_l,z_h]
[xl,xh]×[yl,yh]×[zl,zh]映射到
[
x
l
′
,
x
h
′
]
×
[
y
l
′
,
y
h
′
]
×
[
z
l
′
,
z
h
′
]
[x_l',x_h']\times[y_l',y_h']\times[z_l',z_h']
[xl′,xh′]×[yl′,yh′]×[zl′,zh′]:
w
i
n
d
o
w
=
[
x
h
′
−
x
l
′
x
h
−
x
l
0
0
x
l
′
x
h
−
x
h
′
x
l
x
h
−
x
l
0
y
h
′
−
y
l
′
y
h
−
y
l
0
y
l
′
y
h
−
y
h
′
y
l
y
h
−
y
l
0
0
z
h
′
−
z
l
′
z
h
−
z
l
z
l
′
z
h
−
z
h
′
z
l
z
h
−
z
l
0
0
0
1
]
window = \begin{bmatrix} \frac{x_h'-x_l'}{x_h-x_l} & 0&0&\frac{x_l'x_h-x_h'x_l}{x_h-x_l} \\ 0 & \frac{y_h'-y_l'}{y_h-y_l}&0&\frac{y_l'y_h-y_h'y_l}{y_h-y_l} \\ 0 & 0&\frac{z_h'-z_l'}{z_h-z_l}&\frac{z_l'z_h-z_h'z_l}{z_h-z_l} \\ 0 & 0&0&1 \\ \end{bmatrix}
window=⎣⎢⎢⎢⎡xh−xlxh′−xl′0000yh−ylyh′−yl′0000zh−zlzh′−zl′0xh−xlxl′xh−xh′xlyh−ylyl′yh−yh′ylzh−zlzl′zh−zh′zl1⎦⎥⎥⎥⎤
屏幕映射
在这一步中分别牵扯到两个空间: 归一化设备坐标(下文简称NDC)和屏幕空间.
这里做以下假定:
- 我们需要去渲染的所有顶点都在一个小立方体里, 小立方体的范围为: ( x , y , z ) ∈ [ − 1 , 1 ] 3 (x,y,z)\in[-1,1]^3 (x,y,z)∈[−1,1]3.
- 摄像机朝向为-z方向,up方向为+y方向.
现在我们需要去做的是把正方形 [ − 1 , 1 ] 2 [-1,1]^2 [−1,1]2映射到矩形 [ − 0.5 , n x − 0.5 ] × [ − 0.5 , n y − 0.5 ] [-0.5,n_x-0.5]\times[-0.5,n_y-0.5] [−0.5,nx−0.5]×[−0.5,ny−0.5] 1
根据我们上文的窗口转换可以推导出:
[
x
s
c
r
e
e
n
y
s
c
r
e
e
n
z
s
c
r
e
e
n
1
]
=
[
n
x
2
0
0
n
x
−
1
2
0
n
y
2
0
n
y
−
1
2
0
0
1
0
0
0
0
1
]
[
x
c
a
n
o
n
i
c
a
l
y
c
a
n
o
n
i
c
a
l
z
c
a
n
o
n
i
c
a
l
1
]
\begin{bmatrix} x_{screen}\\ y_{screen}\\ z_{screen}\\ 1 \end{bmatrix}= \begin{bmatrix} \frac{n_x}{2}&0&0&\frac{n_x-1}{2}\\ 0& \frac{n_y}{2}&0&\frac{n_y-1}{2}\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix} \begin{bmatrix} x_{canonical}\\ y_{canonical}\\ z_{canonical}\\ 1 \end{bmatrix}
⎣⎢⎢⎡xscreenyscreenzscreen1⎦⎥⎥⎤=⎣⎢⎢⎡2nx00002ny0000102nx−12ny−101⎦⎥⎥⎤⎣⎢⎢⎡xcanonicalycanonicalzcanonical1⎦⎥⎥⎤
注意这里我们保留了z值 即
z
s
c
r
e
e
n
=
z
c
a
n
o
n
i
c
a
l
z_{screen}=z_{canonical}
zscreen=zcanonical. z值可以用于比较物体的远近.
由此我们得到了屏幕映射矩阵:
M
v
p
=
[
n
x
2
0
0
n
x
−
1
2
0
n
y
2
0
n
y
−
1
2
0
0
1
0
0
0
0
1
]
M_{vp}= \begin{bmatrix} \frac{n_x}{2}&0&0&\frac{n_x-1}{2}\\ 0& \frac{n_y}{2}&0&\frac{n_y-1}{2}\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix}
Mvp=⎣⎢⎢⎡2nx00002ny0000102nx−12ny−101⎦⎥⎥⎤
注意,这里的vp代表的是viewport.
小结
至此,我们知道了给定一个小立方体如何投射到屏幕上. 这里我们忽略了z值,真正渲染的时候z是用来判定物品远近的. 这点在后续的博文中将会更一进步介绍.
正交映射(Orth projection transformation)
在上文中,我们已知如何把小立方体映射到屏幕上. 现在我们把难度升级,假设我们想要渲染一个长方体如下图所示:
由于我们已知如何把小立方体映射到屏幕上,所以如果我们可以把长方体映射到小立方体上即可.
即
[
l
,
r
]
×
[
b
,
t
]
×
[
n
,
f
]
→
[
−
1
,
1
]
3
[l,r]\times[b,t]\times[n,f] \rightarrow [-1,1]^3
[l,r]×[b,t]×[n,f]→[−1,1]3.
利用窗口转换可以得出:
M
o
r
t
h
=
[
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
]
M_{orth}= \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}
Morth=⎣⎢⎢⎡r−l20000t−b20000n−f20−r−lr+l−t−bt+b−n−fn+f1⎦⎥⎥⎤
小结
现在假设给定长方体内的坐标(x,y,z,1). 我们现在可以获得如下公式:
[
x
p
i
x
e
l
y
p
i
x
e
l
z
c
a
n
o
n
i
c
a
l
1
]
=
(
M
v
p
)
(
M
o
r
t
h
)
[
x
y
z
1
]
\begin{bmatrix} x_{pixel}\\y_{pixel}\\z_{canonical}\\1 \end{bmatrix}= (M_{vp})(M_{orth}) \begin{bmatrix} x\\y\\z\\1 \end{bmatrix}
⎣⎢⎢⎡xpixelypixelzcanonical1⎦⎥⎥⎤=(Mvp)(Morth)⎣⎢⎢⎡xyz1⎦⎥⎥⎤
观察变换(CameraSpace transformation)
在上述空间转换中,我们都假定了摄像机朝向为-z,摄像机顶朝向为+y.
假定摄像机的位置在世界坐标为E,三个坐标轴分别为u,v,w.
参考坐标空间转换,可以得到从世界坐标系一点到摄像机坐标系的映射为:
M
c
a
m
=
[
u
v
w
e
0
0
0
1
]
−
1
M_{cam}=\begin{bmatrix} u&v&w&e\\ 0&0&0&1\\ \end{bmatrix}^{-1}
Mcam=[u0v0w0e1]−1
现在我们来思考这四个向量如何获得:
- e为摄像机在世界空间的坐标.
- w为摄像机的反向单位向量. 假定我们设g为从摄像机到观察点的向量.
则 w = − g ∣ ∣ g ∣ ∣ w=-\frac{g}{||g||} w=−∣∣g∣∣g - 然后任意指定u或者v后, 剩下的可以通过w和其叉积求出.
接口考虑
多数情况下,摄像机初始化时的摆放是正方向的. 意味着摄像机是摆正状态,不会饶观察方向旋转.
在这种情况下,我们可以指定一个view-up向量t, 通常情况下选定(0,1,0).
其中v,t,g,w均在同一平面上.此时可以得出下列公式:
w
=
−
g
∣
∣
g
∣
∣
w=-\frac{g}{||g||}
w=−∣∣g∣∣g
u
=
t
×
w
∣
∣
t
×
w
∣
∣
u=\frac{t\times w}{||t\times w||}
u=∣∣t×w∣∣t×w
v
=
w
×
u
v=w \times u
v=w×u
这里我们不直接使用t来当做v是由于t并不一定垂直于w.
但是由于t,v,w同一平面,所以t和w叉乘的结果会垂直于t和w所在的平面,也即v所在的平面. 这代表了u垂直于v和w.
这样在摆正摄像机的前提下,我们只用指定一个暗示方向t即可自动算出v和u了.
小结
综上,我们新获得了一个
M
c
a
m
M_{cam}
Mcam矩阵. 结合上文,从世界空间到屏幕空间的矩阵如下:
M
w
o
r
l
d
→
p
i
x
l
e
=
M
v
p
M
o
r
t
h
M
c
a
m
M_{world\rightarrow pixle}=M_{vp}M_{orth}M_{cam}
Mworld→pixle=MvpMorthMcam
透视投影(Projective Transformation)
不同于正交投影,透视投影是模拟人类眼睛的一种投影方式. 即越远的物体显示的越小,如下图所示:
上图红色位置为摄像机,白色竖线为屏幕,可以看到离屏幕比较近的绿色立方体映射的位置比蓝色要高.
具体的计算过程看下图分析:
这里做如下假定:
摄像机位置位于原点,朝向为-z.
那么根据相似三角形,我们可以得到如下等式:
y
s
y
=
d
−
z
\frac{y_s}{y}=\frac{d}{-z}
yys=−zd
即
y
s
=
d
−
z
×
y
{y_s}=\frac{d}{-z}\times y
ys=−zd×y
用矩阵的表达形式:
y
s
=
[
d
−
z
0
0
1
]
×
[
y
1
]
y_s=\begin{bmatrix} \frac{d}{-z}&0\\ 0&1 \end{bmatrix} \times \begin{bmatrix} y\\ 1 \end{bmatrix}
ys=[−zd001]×[y1]
使矩阵变为常量:
y
s
=
[
−
d
0
0
1
]
×
[
y
z
1
]
y_s=\begin{bmatrix} -d&0\\ 0&1 \end{bmatrix} \times \begin{bmatrix} \frac{y}{z}\\ 1 \end{bmatrix}
ys=[−d001]×[zy1]
设近平面为n,则n=-d,于是我们有以下:
y
s
=
[
n
0
0
1
]
×
[
y
z
1
]
=
[
n
0
0
1
]
×
[
y
z
]
y_s=\begin{bmatrix} n&0\\ 0&1 \end{bmatrix} \times \begin{bmatrix} \frac{y}{z}\\ 1 \end{bmatrix} = \begin{bmatrix} n&0\\ 0&1 \end{bmatrix} \times \begin{bmatrix} y\\ z \end{bmatrix}
ys=[n001]×[zy1]=[n001]×[yz]
x坐标同理获得,于是得到如下矩阵:
[
x
s
y
s
z
s
1
]
=
[
n
0
0
0
0
n
0
0
.
.
.
.
.
.
.
.
.
.
.
.
0
0
1
0
]
×
[
x
y
z
1
]
=
[
n
x
n
y
.
.
.
z
]
=
[
n
x
z
n
y
z
.
.
.
1
]
\begin{bmatrix} x_s\\ y_s\\ z_s\\ 1\\ \end{bmatrix}= \begin{bmatrix} n&0&0&0\\ 0&n&0&0\\ ...&...&...&...\\ 0&0&1&0\\ \end{bmatrix} \times \begin{bmatrix} x\\ y\\ z\\ 1\\ \end{bmatrix} = \begin{bmatrix} nx\\ ny\\ ...\\ z\\ \end{bmatrix} = \begin{bmatrix} \frac{nx}{z}\\ \frac{ny}{z}\\ ...\\ 1\\ \end{bmatrix}
⎣⎢⎢⎡xsyszs1⎦⎥⎥⎤=⎣⎢⎢⎡n0...00n...000...100...0⎦⎥⎥⎤×⎣⎢⎢⎡xyz1⎦⎥⎥⎤=⎣⎢⎢⎡nxny...z⎦⎥⎥⎤=⎣⎢⎢⎡znxzny...1⎦⎥⎥⎤
综上,我们已经获得了x和y的处理方案.接下来我们看下z值如何处理.
第一种方案就是和正交投影一样,我们不让z值改变.这样我们就得到了一个长方体.然后我们再继续做正交投影即可.
我们假设矩阵的第三行分别为a,b,c,d.
于是
z
s
=
a
x
+
b
y
+
c
z
+
d
z
z_s=\frac{ ax+by+cz+d}{z}
zs=zax+by+cz+d
由于x和y坐标与
z
s
z_s
zs是无关的.所以a和b代入0:
z
s
=
c
z
+
d
z
=
c
+
d
z
z_s=\frac{cz+d}{z}=c+\frac{d}{z}
zs=zcz+d=c+zd
由于我们想保留z值,那么可以尝试解决这个等式. 分别代入近平面和远平面:
代入近平面
z
s
=
z
=
n
=
c
+
d
n
z_s=z=n=c+\frac{d}{n}
zs=z=n=c+nd
代入远平面
z
s
=
z
=
f
=
c
+
d
f
z_s=z=f=c+\frac{d}{f}
zs=z=f=c+fd
把n和f当已知值,c和d当未知值,即二元一次方程组.解得:
c
=
n
+
f
d
=
−
f
n
c=n+f \quad d=-fn
c=n+fd=−fn
让我们把c和d代入原等式:
z
s
=
c
+
d
z
=
(
n
+
f
)
+
−
f
n
z
z_s=c+\frac{d}{z}=(n+f)+\frac{-fn}{z}
zs=c+zd=(n+f)+z−fn
这里可以看出
z
s
z_s
zs和z无法成为线性关系.其中-fn<0,z<0,
−
f
n
z
>
0
\frac{-fn}{z}>0
z−fn>0.
我们缓慢的让z变小,即向摄像机朝向移动,则
−
f
n
z
\frac{-fn}{z}
z−fn减小,
z
s
z_s
zs减小.
由此可知:
z
s
z_s
zs最大为n,此时
z
s
z_s
zs位于近平面.
朝着摄像机朝向移动,
z
s
z_s
zs减小.
z
s
z_s
zs最小为f,此时
z
s
z_s
zs位于远平面.
这样随无法保留z值,但是z值得顺序得以保留.代入我们计算的c和d,我们得到:
P
=
[
n
0
0
0
0
n
0
0
0
0
n
+
f
−
f
n
0
0
1
0
]
P= \begin{bmatrix} n&0&0&0\\ 0&n&0&0\\ 0&0&n+f&-fn\\ 0&0&1&0\\ \end{bmatrix}
P=⎣⎢⎢⎡n0000n0000n+f100−fn0⎦⎥⎥⎤
注意此时我们得到的矩阵是从摄像机空间到长方体的映射. 而投影则是把摄像机空间映射到小立方体即NDC上.
于是 我们得到
M
p
e
r
=
M
o
r
t
h
P
M_{per}=M_{orth}P
Mper=MorthP
让我们把上文推导出的
M
o
r
t
h
M_{orth}
Morth代入:
M
p
e
r
=
[
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
−
f
n
0
0
1
0
]
M_{per}= \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} \times \begin{bmatrix} n&0&0&0\\ 0&n&0&0\\ 0&0&n+f&-fn\\ 0&0&1&0\\ \end{bmatrix}
Mper=⎣⎢⎢⎡r−l20000t−b20000n−f20−r−lr+l−t−bt+b−n−fn+f1⎦⎥⎥⎤×⎣⎢⎢⎡n0000n0000n+f100−fn0⎦⎥⎥⎤
M
p
e
r
=
[
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
]
M_{per}= \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}
Mper=⎣⎢⎢⎡r−l2n0000t−b2n00l−rl+rb−tb+tn−ff+n100f−n2fn0⎦⎥⎥⎤
额外
模型变换 (Modelling transformation)
模型变换其实就是简单的坐标系变换.可以参考坐标空间转换
裁剪空间(ClipSpace)
首先明确一点,裁剪空间是在NDC的前一步发生的.也就是映射到小立方体之前.
对于非透视投影:
M
m
o
d
e
l
→
w
o
r
l
d
→
c
a
m
e
r
a
→
o
r
t
h
M_{model\rightarrow world \rightarrow camera \rightarrow orth}
Mmodel→world→camera→orth 裁剪后 除以w到NDC.
对于透视投影:
M
m
o
d
e
l
→
w
o
r
l
d
→
c
a
m
e
r
a
→
p
e
r
s
M_{model\rightarrow world \rightarrow camera \rightarrow pers}
Mmodel→world→camera→pers 裁剪后 除以w到NDC.
在上述描述中裁剪的所在位置就是ClipSpace.
这里面所有的坐标都要与w进行比较,只有大于等于-w并且小于等于w时才可以进入小立方体. 注意这里的w对于每一个点都是不一样的.
这里我们可以反向理解,只有在小立方体(NDC)的点才会被渲染,所以在NDC中只有满足大于等于-1小于等于1的点会被渲染. 那么在除之前 自然只有大于等于-w且小于等于w才能被渲染.
Z-fighting
假设
z
e
z_e
ze代表的是相机空间的z值,
z
n
z_n
zn代表透视投影中正交投影前的z值.
我们上文推导中:
z
n
=
c
+
d
z
e
=
(
n
+
f
)
+
−
f
n
z
e
z_n=c+\frac{d}{z_e}=(n+f)+\frac{-fn}{z_e}
zn=c+zed=(n+f)+ze−fn
函数图像2为下图所示:
可以发现当近平面和远平面距离很远的时候,
z
e
z_e
ze及时发生了较大的改变,对于
z
n
z_n
zn来讲,只是一点点的变化. 那么当精度不够时,就会产生所谓的Z-fighting现象.
总结
每个空间转换单独来理解都是比较好理解的. 比较难理解的透视投影也可以拆成先映射到正交投影再映射到NDC中. 对于渲染中的空间转换相关知识看了很多资料总是一知半解, 主要原因在于有些知识囫囵吞枣,另外没有亲自动手推导过.
好比摄像机的Up Vector, 本来以为自己很清楚了,但是在写blog的过程中发现.如果绕着摄像机观察方向旋转,此时不可以简单的指定Vector.up为(0,1,0).