DX正交投影

正交投影

正交投影,之所以这么称呼是因为所有的投影线都与最终的绘图表面垂直,是一种相对简单的投影技术。视域体---也就是包含所有你想显示的几何体的可视空间---是一个将被变换到规范视域体的轴对齐盒子,见图2

DX正交投影_第1张图片

                                  图2: 正交投影

正如你看见的,视域体由6个面定义:

DX正交投影_第2张图片

因为视域体和规范视域体都是轴对齐盒子,这种类型的投影没有距离更正。最终的结果是,事实上,很像图1那样每个坐标点只是丢弃了z坐标。对象在3D空间中的大小和在投影中的大小相同,即使一个对象比另一个对象距离摄像机远很多。在3D空间中平行的直线在最终的图像上也是平行的。使用这种类型的投影将出现一些问题像第一人称射击游戏---试想一下在不知道任何东西有多远的情况下玩!---但它也有它的用处。你可能在格子游戏中使用它,例如,特别是摄像机被绑定在一个固定角度的一款格子游戏中,图3显示了1个简单的例子

DX正交投影_第3张图片

                    图3: 正交投影的一个简单例子

所以,事不宜迟,现在开始弄清楚它是如何工作的。最简单的方法可能是3个坐标轴分开考虑,并且计算如何沿着每个坐标轴将点从视域体映射到规范视域体。从x轴开始。视域体中的点的x坐标范围在[l, r],想把它变换到范围在[-1, 1]

DX正交投影_第4张图片

现在,准备把范围缩小到我们期望的,各项减去l,这样,最左边的项变为0。另一种可能考虑的做法是平移范围使其以0为中心,而不是一端为0,但现在这种方式代数式更整洁,所以为了可读性起见我将以现在这种方式做

DX正交投影_第5张图片

现在,范围的一端是0,你可以缩小到期望的大小。你期望x值的范围是2个单位宽,从1到-1,所以把各项乘以2/(r-l)。注意r-l是视域体的宽度,因此始终是一个正数,所以不用担心不等号会改变方向。

DX正交投影_第6张图片

下一步,各项减去1就产生了我们期望的范围[-1, 1]

DX正交投影_第7张图片

基本代数允许我们将中间项写成一个单一的分数

DX正交投影_第8张图片

最后,把中间项分成2部分使它形如px+q的形式,我们需要把项组织成这种形式这样我们推导的公式就可以简单的转换成矩阵形式。

DX正交投影_第9张图片

这个不等式的中间项告诉了我们把x转换到规范视域体的公式

DX正交投影_第10张图片

获取y的变换公式的步骤是完全一样的---只要用y替代x,用t替代r,用b替代l---所以这里不重复它们了,只是给出结果

DX正交投影_第11张图片

最后,需要推倒z的变换公式。z的推导有点点不同,因为需要把z映射到范围[0, 1]而不是[-1, 1],但看上去很相似。z坐标最开始在范围[n, f]

DX正交投影_第12张图片

把各项减去n,这样的话范围的下限就变为了0

DX正交投影_第13张图片

现在剩余要做的就是除以f-n,这样就产生了最终的范围[0, 1]。和前面相同,注意f-n是视域体的深度所以绝对不会为负

DX正交投影_第14张图片

最后,把它分成2部分使它形如px+q的形式

DX正交投影_第15张图片

这样便给出了z的变换公式

DX正交投影_第16张图片

现在,可以准备写正交投影矩阵了。总结到目前为止的工作,推导了3个投影公式

DX正交投影_第17张图片

如果写成矩阵形式,就得到了

DX正交投影_第18张图片

就是这样!Direct3D提供了D3DXMatrixOrthoOffCenterLH()(what a mouthful!)方法构造一个和这个公式相同的正交投影矩阵;你可以在DirectX文档中找到。方法名中的"LH"代表了你正在使用左手坐标系。但是,究竟"OffCenter"的意思是什么呢?

这一问题的答案引导你到一个正交投影矩阵的简化形式。考虑几点: 首先,在可见空间中,摄像机定位在原点并且沿着z轴方向观看。第二,你通常希望你的视野在左右方向上延伸的同样远,并且在z轴的上下方向上也延伸的同样远。如果是这样的情况,那么z轴正好直接穿过你视域体的的中心,所以得到了r = -l并且t = -b。换句话说,你可以把r, l, t和b一起忘掉,简单的把视域体定义为1个宽度w和1个高度h,以及裁剪面f和n。如果你在正交投影矩阵中应用上面说的,那么你将得到这个相当简化的版本

DX正交投影_第19张图片

这个公式是Direct3D中D3DXMatrixOrthoLH()方法的实现。你几乎可以一直使用这个矩阵替代上面那个你推导的更通用的"OffCenter"版本,除非你用投影做些奇怪的事情。

在完成这部分之前还有一点。它启发我们注意到这个矩阵可以用两个简单的变换串联替代: 平移其次是缩放。如果你思考几何的话这对你是有意义的,因为所有你在正交投影中做的就是从一个轴对齐盒子转向另一个轴对齐盒子;视域体不改变它的形状,只改变它的位置和大小。具体来说,有

DX正交投影_第20张图片

这种投影方式可能更直观一点因为它让你更容易想象发生了什么。首先,视域体沿着z轴平移使它的近平面和原点重合;然后,应用一个缩放把它缩小到规范视域体大小。很容易理解吧,对不对?一个偏离中心(OffCenter)的正交投影矩阵也可以用一个变换和一个缩放代替,它和上面的结果很相似所以我在这里不列出了。

上面就是正交投影,现在可以去接触一些更有挑战性的东西了。

你可能感兴趣的:(Ogre)