资源预览内容
第1页 / 共15页
第2页 / 共15页
第3页 / 共15页
第4页 / 共15页
第5页 / 共15页
第6页 / 共15页
第7页 / 共15页
第8页 / 共15页
第9页 / 共15页
第10页 / 共15页
亲,该文档总共15页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume)中,待裁剪完毕后进行透视除法的行为。在算法中它是通过透视矩阵乘法和透视除法两步完成的。透视投影变换是令很多刚刚进入3D图形领域的开发人员感到迷惑乃至神秘的一个图形技术。其中的理解困难在于步骤繁琐,对一些基础知识过分依赖,一旦对它们中的任何地方感到陌生,立刻导致理解停止不前。没错,主流的3D APIs如OpenGL、D3D的确把具体的透视投影细节封装起来,比如gluPerspective() 就可以根据输入生成一个透视投影矩阵。而且在大多数情况下不需要了解具体的内幕算法也可以完成任务。但是你不觉得,如果想要成为一个职业的图形程序员或游 戏开发者,就应该真正降伏透视投影这个家伙么?我们先从必需的基础知识着手,一步一步深入下去(这些知识在很多地方可以单独找到,但我从来没有在同一个地 方全部找到,但是你现在找到了)。我们首先介绍两个必须掌握的知识。有了它们,我们才不至于在理解透视投影变换的过程中迷失方向(这里会使用到向量几何、矩阵的部分知识,如果你对此不是很熟悉,可以参考下载 (1.67 KB)2010-4-25 01:02可以找到一组坐标(v1,v2,v3),使得v = v1 a + v2 b + v3 c (1)而对于一个点p,则可以找到一组坐标(p1,p2,p3),使得p o = p1 a + p2 b + p3 c (2)从上面对向量和点的表达,我们可以看出为了在坐标系中表示一个点(如p),我们把点的位置看作是对这个基的原点o所进行的一个位移,即一个向量p o(有的书中把这样的向量叫做位置向量起始于坐标原点的特殊向量),我们在表达这个向量的同时用等价的方式表达出了点p:p = o + p1 a + p2 b + p3 c (3)(1)(3)是坐标系下表达一个向量和点的不同表达方式。这里可以看出,虽然都是用代数分量的形式表达向量和点,但表达一个点比一个向量需要额外的信息。如果我写出一个代数分量表达(1, 4, 7),谁知道它是个向量还是个点!我们现在把(1)(3)写成矩阵的形式:下载 (2.39 KB)2010-4-25 01:02这里(a,b,c,o)是坐标基矩阵,右边的列向量分别是向量v和点p在基下的坐标。这样,向量和点在同一个基下就有了不同的表达:3D向量的第4个代数分量是0,而3D点的第4个代数分量是1。像这种这种用4个代数分量表示3D几何概念的方式是一种齐次坐标表示。“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。” F.S. Hill, JR这样,上面的(1, 4, 7)如果写成(1,4,7,0),它就是个向量;如果是(1,4,7,1),它就是个点。下面是如何在普通坐标 (Ordinary Coordinate)和齐次坐标(Homogeneous Coordinate)之间进行转换:从普通坐标转换成齐次坐标时,如果(x,y,z)是个点,则变为(x,y,z,1);如果(x,y,z)是个向量,则变为 (x,y,z,0)从齐次坐标转换成普通坐标时,如果是(x,y,z,1),则知道它是个点,变成(x,y,z);如果是(x,y,z,0),则知道它是个向量,仍然变成(x,y,z)以上是通过齐次坐标来区分向量和点的方式。从中可以思考得知,对于平移T、旋转R、缩放S这3个最常见的仿射变换,平移变换只对于点才有意义,因为普通向量没有位置概念,只有大小和方向,这可以通过下面的式子清楚地看出:下载 (3.69 KB)2010-4-25 01:02而旋转和缩放对于向量和点都有意义,你可以用类似上面齐次表示来检测。从中可以看出,齐次坐标用于仿射变换非常方便。此外,对于一个普通坐标的点P=(Px, Py, Pz),有对应的一族齐次坐标(wPx, wPy, wPz, w),其中w不等于零。比如,P(1, 4, 7)的齐次坐标有(1, 4, 7, 1)、(2, 8, 14, 2)、(-0.1, -0.4, -0.7, -0.1)等等。因此,如果把一个点从普通坐标变成齐次坐标,给x,y,z乘上同一个非零数w,然后增加第4个分量w;如果把一个齐次坐标转换成普通坐 标,把前三个坐标同时除以第4个坐标,然后去掉第4个分量。由于齐次坐标使用了4个分量来表达3D概念,使得平移变换可以使用矩阵进行,从而如F.S. Hill, JR所说,仿射(线性)变换的进行更加方便。由于图形硬件已经普遍地支持齐次坐标与矩阵乘法,因此更加促进了齐次坐标使用,使得它似乎成为图形学中的一个标准。简单的线性插值这是在图形学中普遍使用的基本技巧, 我们在很多地方都会用到,比如2D位图的放大、缩小,Tweening变换,以及我们即将看到的透视投影变换等等。基本思想是:给一个x属于a, b,找到y属于c, d,使得x与a的距离比上ab长度所得到的比例,等于y与c的距离比上cd长度所得到的比例,用数学表达式描述很容易理解:下载 (1.15 KB)2010-4-25 01:02这样,从a到b的每一个点都与c到d上的唯一一个点对应。有一个x,就可以求得一个y。此外,如果x不在a, b内,比如x b,则得到的y也是符合y d,比例仍然不变,插值同样适用。透视投影变换好,有了上面两个理论知识,我们开始分析这次的主角透视投影变换。这里我们选择OpenGL的透视投影变换进行分析,其他的 APIs会存在一些差异,但主体思想是相似的,可以类似地推导。经过相机矩阵的变换,顶点被变换到了相机空间。这个时候的多边形也许会被视锥体裁剪,但在 这个不规则的体中进行裁剪并非那么容易的事情,所以经过图形学前辈们的精心分析,裁剪被安排到规则观察体(Canonical View Volume, CVV)中进行,CVV是一个正方体,x, y, z的范围都是-1,1,多边形裁剪就是用这个规则体完成的。所以,事实上是透视投影变换由两步组成:1)用透视变换矩阵把顶点从视锥体中变换到裁剪空间的CVV中。2)CVV裁剪完成后进行透视除法(一会进行解释)。下载 (4.25 KB)2010-4-25 01:02我们一步一步来,我们先从一个方向考察投影关系。下载 (3.28 KB)2010-4-25 01:02上图是右手坐标系中 顶点在相机空间中的情形。设P(x,z)是经过相机变换之后的点,视锥体由eye眼睛位置,np近裁剪平面,fp远裁剪平面组成。N是眼睛到 近裁剪平面的距离,F是眼睛到远裁剪平面的距离。投影面可以选择任何平行于近裁剪平面的平面,这里我们选择近裁剪平面作为投影平面。设 P(x,z)是投影之后的点,则有z = -N。通过相似三角形性质,我们有关系:下载 (1.28 KB)2010-4-25 01:02同理,有下载 (1.01 KB)2010-4-25 01:02这样,我们便得到了P投影后的点P下载 (1.23 KB)2010-4-25 01:02从上面可以看出,投影的结果z始终等于-N,在投影面上。实际上,z对于投影后的P已经没有意义了,这个信息点已经没用了。但对于3D图形管线来 说,为了便于进行后面的片元操作,例如z缓冲消隐算法,有必要把投影之前的z保存下来,方便后面使用。因此,我们利用这个没用的信息点存储z,处理成:下载 (1.25 KB)2010-4-25 01:02这个形式最大化地使用了3个信息点,达到了最原始的投影变换的目的,但是它太直白了,有一点蛮干的意味,我感觉我们最终的结果不应该是它,你说呢?我们开始结合CVV进行思考,把它写得在数学上更优雅一致,更易于程序处理。假入能够把上面写成这个形式:下载 (1.39 KB)2010-4-25 01:02那么我们就可以非常方便的用矩阵以及齐次坐标理论来表达投影变换:下载 (3.51 KB)2010-4-25 01:02其中下载 (1.99 KB)2010-4-25 01:02哈,看到了齐次坐标的使用,这对于你来说已经不陌生了吧?这个新的形式不仅达到了上面原始投影变换的目的,而且使用了齐次坐标理论,使得处理更加规范化。注意在把 下载 (1.29 KB)2010-4-25 01:02变成 下载 (1.51 KB)2010-4-25 01:02的一步我们是使用齐次坐标变普通坐标的规则完成的。这一步在透视投影过程中称为透视除法(Perspective Division),这是透视投影变换的第2步,经过这一步,就丢弃了原始的z值(得到了CVV中对应的z值,后面解释),顶点才算完成了投影。而在这两 步之间的就是CVV裁剪过程,所以裁剪空间使用的是齐次坐标 下载 (1.29 KB)2010-4-25 01:02,主要原因在于透视除法会损失一些必要的信息(如原始z,第4个-z保留的)从而使裁剪变得更加难以处理,这里我们不讨论CVV裁剪的细节,只关注透视投影变换的两步。矩阵下载 (1.53 KB)2010-4-25 01:02就是我们投影矩阵的第一个版本。你一定会问为什么要把z写成下载 (1.01 KB)2010-4-25 01:02有两个原因:1)P的3个代数分量统一地除以分母-z,易于使用齐次坐标变为普通坐标来完成,使得处理更加一致、高效。2)后面的CVV是一个x,y,z的范围都为-1,1的规则体,便于进行多边形裁剪。而我们可以适当的选择系数a和b,使得 下载 (1.01 KB)2010-4-25 01:02这个式子在z = -N的时候值为-1,而在z = -F的时候值为1,从而在z方向上构建CVV。接下来我们就求出a和b:下载 (1.99 KB)2010-4-25 01:02这样我们就得到了透视投影矩阵的第一个版本:下载 (2.53 KB)2010-4-25 01:02使用这个版本的透视投影矩阵可以从z方向上构建CVV,但是x和y方向仍然没有限制在-1,1中,我们的透视投影矩阵的下一个版本就要解决这个问题。为了能在x和y方向把顶点从Frustum情形变成CVV情形,我们开始对x和y进行处理。先来观察我们目前得到的最终变换结果:下载 (1.51 KB)2010-4-25 01:02我们知道-Nx / z的有效范围是投影平面的左边界值(记为left)和右边界值(记为right),即left, right,-Ny / z则为bottom, top。而现在我们想把-Nx / z属于left, right映射到x属于-1, 1中,-Ny / z属于bottom, top映射到y属于-1, 1中。你想到了什么?哈,就是我们简单的线性插值,你都已经掌握了!我们解决掉它:下载 (4.37 KB)201
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号