DIX 的透视投影变换.doc_第1页
DIX 的透视投影变换.doc_第2页
DIX 的透视投影变换.doc_第3页
DIX 的透视投影变换.doc_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

DIX 的透视投影变换所谓透视投影变换,就是view 空间到project 空间的带透视性质的坐标变换步骤(这两个空间的定义可以参考其他文档和书籍)。我们首先来考虑它应该具有那些变换性质。很显然,它至少要保证我们在view空间中所有处于可视范围内的点通过变换之后,统统落在project空间的可视区域内。好极了,我们就从这里着手先来看看两个空间的可视区域。由于是透视变换,view空间中的可见范围既是常说的视平截体(view frustum)。如图,(图1)它就是由前后两个截面截成的这个棱台。从view空间的x正半轴看过去是下图这个样子。(图2)接下来是project空间的可视范围。这个空间应当是处于你所见到的屏幕上。实际上将屏幕表面视作project空间的xoy平面,再加一条垂直屏幕向里(或向外)的z轴(这取决于你的坐标系是左手系还是右手系),这样就构成了我们想要的坐标系。好了,现在我们可以用视口(view port)的大小来描述这个可视范围了。比如说全屏幕640*480的分辨率,原点在屏幕中心,那我们得到的可视区域为一个长方体,它如下图(a)所示。(图3)但是,这样会带来一些设备相关性而分散我们的注意力,所以不妨先向DirectX文档学学,将project空间的可视范围定义为x-1,1, y-1,1, z0,1的一个立方体(上图b)。这实际上可看作一个中间坐标系,从这个坐标系到上面我们由视口得出的坐标系,只需要对三个轴向做一些放缩和平移操作即可。另外,这个project坐标系对clip操作来说,也是比较方便的。2. 推导过程 先从project空间的x正半轴看看我们的变换目标。(图4)这个区域的上下边界为y=1, 而图2中的上下边界为y = z * tan(fov/2),要实现图2到图4的变换,我们有y = y * cot(fov/2) / z。这下完了,这是一个非线性变换,怎么用矩阵计算来完成呢?还好我们有w这个分量。注意到我们在做投影变换之前所进行的两次坐标变换world变换和view变换,他们只是一系列旋转平移和缩放变换的叠加。仔细观察这些变换矩阵,你会发现它们其实不会影响向量的w分量。换句话说,只要不是故意,一个w分量等于1的向量,再来到投影变换之前他的w分量仍旧等于1。好的,接下来我们让w= w*z, 新的w就记录下了view空间中的z值。同时在y分量上我们退而求其次,只要做到y = y * cot(fov/2)。那么,在做完线性变换之后,我们再用向量的y除以w,就得到了我们想要的最终的y值。x分量的变换可以如法炮制,只是fov要换一换。事实上,很多用以生成投影变换矩阵的函数都使用了aspect这个参数。这个参数给出了视平截体截面的纵横比(这个比值应与view port的纵横比相等,否则变换结果会失真)。如果我们按照惯例,定义aspect = size of X / size of Y。那么我们就可以继续使用同一个fov而给出x分量的变换规则:x = x * cot(fov/2) / aspect。现在只剩下z分量了。我们所渴望的变换应将z = Znear 变换到z = 0,将z = Zfar变换到z = 1。这个很简单,但是等等,x, y最后还要除以w,你z怎能例外。既然也要除,那么z = Zfar 就不能映射到z = 1了。唔,先映射到z = Zfar试试。于是,有z = Zfar*(z-Znear)/(Zfar Znear)。接下来,看看z/z的性质。令f(z) = z/z = Zfar*(z-Znear)/(z*(Zfar Znear))。则f(z) = Zfar * Znear / ( z2 * (Zfar Znear ), 显而易见f(z) 0。所以除了z = 0是一个奇点,函数f(z)是一个单调增的函数。因此,当ZnearzZfar时,f(Znear)f(z)f(Zfar),即0f(z)1。至此,我们可以给出投影变换的表达式了。x = x*cot(fov/2)/aspecty = y*cot(fov/2)z = z*Zfar / ( Zfar Znear ) Zfar*Znear / ( Zfar Znear )w = z以矩阵表示,则得到变换矩阵如下,cot(fov/2)/aspect 0 0 0 0 cot(fov/2) 0 0 0 0 Zfar/(Zfar-Znear) 1 -(zf+zn)/(zf-zn) ,-10 0 -Zfar*Znear/(Zfar-Znear) 0。 -2 * (Zfar*Znear/(Zfar-Znear)做完线性变换之后,再进行所谓的“归一化”,即用w分量去除结果向量。x = x*cot(fov/2)/aspecty = y*cot(fov/2)z = z*Zfar / ( Zfar Znear ) Zfar*Znear / ( Zfar Znear )w = z对于求取出来的x,y,z,wglProject(object_xyz,modematrix,promatrix,vp,win_xyz)可以用函数求出w,也可以依据z, Zfar , Znear来反响求取z,也就是w,“归一化”:Xo=x/X;Yo=y/Y;Zo=z/w;现在我们考虑一下这个变换对全view空间的点的作用。首先是x和y分量,明了地,当z0时,一切都如我们所愿;当z0时,x和y的符号在变换前后发生了变化,从图象上来说,view空间中处于camera后面的图形经过变换之后上下颠倒,左右交换;当z= 0 时,我们得到的结果是无穷大。这个结果在实际中是没有意义的,以后我们得想办法弄掉它。再来看z,仍旧拿我们上面定义的f(z)函数来看,我们已经知道当zZfar时,f(z)1;同时当z+,f(z)Zfar/(Zfar-Znear);当z+0时,f(z)-; z-0时,f(z)+; z时,f(z)Zfar/(Zfar-Znear).由此我们画出f(z)的图像。(图5)由此图可以看出当z0时,如果我们仍旧使用f(z)进行绘制会产生错误。所以我们会想需要clip操作只要这个三角形有任意一个顶点经过变换后z值落在Zfar/(Zfar-Z

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论