本文主要描述在3D中,将一个点坐标变换到屏幕坐标的变换过程。
首先对于这个过程为:Object Space->World Space->View Space->Clip Space->Screen Space.
1:世界变换(World Transformation)
对于一个模型,他自身的建模是根据自己的一个坐标系(Object Space)来建立的,但是对于一个场景,整个场景是在统一的一个坐标系(World Space)之下建立的,那么模型从Object Space到World Space,通常需要缩放(Scaling),旋转(Rotation),平移(Translation),最后到达World Space。所以这个过程的变换矩阵通常是缩放矩阵,旋转矩阵和平移矩阵的结合。注意:他们之间的顺序代表了先经过什么变换再经过什么变换。
2:视图变换(View Transformation)
在Pipeline中,View Transformation完成的工作是将World Space变换到View Space中去,在View Space中,Eye Position为该坐标系的原点,(LeftVec, UpVec,ViewVec)构成了View Space中对应的(X, Y, Z)基向量。
从World Space到View Space的过程:
1:平移,将World Space中的坐标原地移到View Space中的坐标原点
2:旋转,将World Space中的(X, Y, Z)旋转和View Space中的(X, Y, Z)对齐
所以这个过程的矩阵为:
V = |1 0 0 0| * |LeftVec.x UpVec.x ViewVec.x 0|
|0 1 0 0| |LeftVec.y UpVec.y ViewVec.y 0|
|0 0 1 0| |LeftVec.z UpVec.z ViewVec.z 0|
|-Ex -Ey -Ez 1| |0 0 0 1|
详细过程可参见前面的"不同坐标系下的坐标变换"。
图示:
3:投影变换(Projection Transformation)
对于一个Camera而言,指定他的可视张角(在水平和垂直两个方向的张角),那它看出去会形成一个金字塔形的视域,如果定义这个Camera的可见近平面(Near Plane)和远平面(Far Plane),这个视域就会构成一个视见体(View Frustum)。
如图所示:
而Projection Transformation的目的就是要将这个View Frustum变成一个方体形。
对于讨论X的过程
图示:
在这个图中:对于一点(x,y,z),需要求出在Near Plane上Eye Ray的交点,注意:这里Near Plane实际上在最后就是要渲染的Screen。
得到
xn = x*N/z
同理对于yn
yn = y*N/z
而图中得到的一个方形,他的边长为2*Wn,需要将它变为2*1(即对于xn的范围[-1,1])的方形
所以
xc = xn/Wn = x/(z*tan(Ha/2))
yc = yn/Hn = y/(z*tan(Va/2))
对于zc,他代表了最后这个点的深度值,范围为[0,1],这个范围的边界分别代表了Near Plane和Far Plane。
一种:
zc = (z-N)/(F-N),但是这种方法不便于后面矩阵的表示
所以:
zc = F*(z-N)/(z*(F-N))
即zc = ((z-N)/(F-N))/(z/F),可以证明z在[N,F]的范围总是有(z-N)/(F-N) <= z/F,在z==F时取等
最后得到在Clip Space中的坐标形式
xc = x/(z*tan(Ha/2))
yc = y/(z*tan(Va/2))
zc = F*(z-N)/(z*(F-N)) = z*F/(z*(F-N))-F*N/(z*(F-N))
w = 1 (w为后面统一化(Homogeneous Normalization)需要用到的一维,也就是x,y,z都除以w)
将上面的变化一下
xc = x*cot(Ha/2)
yc = y*cot(Va/2)
zc = z*F/(F-N)-F*N/(F-N)
w = z
所以现在构造的矩阵P要满足
(x, y, z, 1)*P = (xc, yc, zc, w)
这里(x,y,z,1)为在View Space中的坐标
从上面的最后的结果可以得到P
P = |cot(Ha/2) 0 0 0|
| 0 cot(Va/2) 0 0|
| 0 0 F/(F-N) 1|
| 0 0 -F*N/(F-N) 0|
这就是最后需要投影变换的投影矩阵。
对于最后得到的Clip Space的坐标:
处于View frustum中的点一定满足:
-w <= xc <= w
-w <= yc <= w
0 <= zc <= w
当经过Homogeneous Normalization过后xc/w和yc/w分别处于[-1,1]的范围。
Homogeneous Normalization部分在Hardware中完成。
4: 视点变换(Viewpoint Transformation)
在Projection Transformation过后(并经过了Homogeneous Normalization)得到了Clip Space中的坐标(xc, yc, zc, 1),这里面-1<=xc<=1, -1<=yc<=1,0<=zc<=1,实际上就是一个Rectangle,这里的变换就是要将这个Rectangle映射到Screen上去。
如下所示:
(-1,1)--------(1,1) ===> (0,0)-----------(W,0)
| | | |
| | | |
(-1,-1)------(1,-1) (0,H)-----------(W,H)
W : Width of the screen
H : Height of the screen
直接根据上面的图实际上就是x*0.5*W+0.5*W, y*(-0.5)*H+0.5*H
即得到矩阵
|0.5*W 0 0 0|
| 0 -0.5*H 0 0|
| 0 0 1 0|
|0.5*W 0.5*H 0 1|
为了表示像素点的中间,则上面的结果x,y分别再加一个0.5/W,0.5/H
最后得到视点变换矩阵
|0.5*W 0 0 0|
| 0 -0.5*H 0 0|
| 0 0 1 0|
|0.5*W+0.5/W 0.5*H+0.5/H 0 1|
经过上面的过程,则整个的几何变换矩阵记为G
G = W*V*P*Vp
G : Geometry Matrix
W : World Matrix
P : Projection Matrix
Vp : Viewpoint Matrix
注:本文采用的点与矩阵乘法形式为 Vector*Matrix