Chinaunix首页 | 论坛 | 博客
  • 博客访问: 174363
  • 博文数量: 43
  • 博客积分: 827
  • 博客等级: 准尉
  • 技术积分: 487
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-26 19:19
文章分类

全部博文(43)

文章存档

2015年(1)

2014年(1)

2013年(5)

2012年(36)

我的朋友

分类: WINDOWS

2012-03-27 19:50:11

本文主要描述在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
阅读(1248) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~