D3D透视投影矩阵推导

合集下载

深入探索透视投影变换

深入探索透视投影变换

深入探索透视投影变换最近更新:2013年11月22日-Twinsen编写-本人水平有限,疏忽错误在所难免,还请各位数学高手、编程高手不吝赐教-email: popyy@透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume)中,待裁剪完毕后进行透视除法的行为。

在算法中它是通过透视矩阵乘法和透视除法两步完成的。

透视投影变换是令很多刚刚进入3D图形领域的开发人员感到迷惑乃至神秘的一个图形技术。

其中的理解困难在于步骤繁琐,对一些基础知识过分依赖,一旦对它们中的任何地方感到陌生,立刻导致理解停止不前。

没错,主流的3D APIs如OpenGL、D3D的确把具体的透视投影细节封装起来,比如gluPerspective(…)就可以根据输入生成一个透视投影矩阵。

而且在大多数情况下不需要了解具体的内幕算法也可以完成任务。

但是你不觉得,如果想要成为一个职业的图形程序员或游戏开发者,就应该真正降伏透视投影这个家伙么?我们先从必需的基础知识着手,一步一步深入下去(这些知识在很多地方可以单独找到,但我从来没有在同一个地方全部找到,但是你现在找到了 )。

我们首先介绍两个必须掌握的知识。

有了它们,我们才不至于在理解透视投影变换的过程中迷失方向(这里会使用到向量几何、矩阵的部分知识,如果你对此不是很熟悉,可以参考《向量几何在游戏编程中的使用》系列文章)。

齐次坐标表示透视投影变换是在齐次坐标下进行的,而齐次坐标本身就是一个令人迷惑的概念,这里我们先把它理解清楚。

根据《向量几何在游戏编程中的使用6》中关于基的概念。

对于一个向量v以及基oabc,可以找到一组坐标(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)是坐标系下表达一个向量和点的不同表达方式。

2d到3d转换 计算公式

2d到3d转换 计算公式

2d到3d转换计算公式
2D到3D的转换可以通过不同的方法实现,其中最常用的方法是透视投影。

透视投影是一种将二维平面上的点映射到三维空间中的方法,可以模拟人眼观察物体时的透视效果。

在透视投影中,可以使用以下计算公式将二维坐标转换为三维坐标:
x' = x (d / z)。

y' = y (d / z)。

z' = d.
其中,(x, y)是二维平面上的点坐标,(x', y', z')是转换后的三维坐标,d是观察者与投影平面的距离,z是物体在二维平面上的深度。

这个公式的意思是,通过将二维坐标的x和y值乘以观察者与投影平面的距离与物体在二维平面上的深度的比例,可以得到转换
后的三维坐标的x'和y'值。

而z'的值则等于观察者与投影平面的距离。

需要注意的是,这个公式只能将二维坐标转换为三维坐标的近似值,因为在实际情况中,存在着很多其他因素,如相机的镜头参数、透视效果的强度等,都会影响到最终的转换结果。

除了透视投影,还有其他的方法可以进行2D到3D的转换,如立体投影、三角测量等,每种方法都有其特定的计算公式和应用场景。

具体使用哪种方法,取决于你的需求和具体情况。

总之,2D到3D的转换是一个复杂的过程,需要考虑多个因素和采用适当的方法来实现。

以上是透视投影方法的计算公式,希望对你有所帮助。

CG透视变换推导汇总

CG透视变换推导汇总

透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume)中,待裁剪完毕后进行透视除法的行为。

在算法中它是通过透视矩阵乘法和透视除法两步完成的。

透视投影变换是令很多刚刚进入3D图形领域的开发人员感到迷惑乃至神秘的一个图形技术。

其中的理解困难在于步骤繁琐,对一些基础知识过分依赖,一旦对它们中的任何地方感到陌生,立刻导致理解停止不前。

没错,主流的3D APIs如OpenGL、D3D的确把具体的透视投影细节封装起来,比如gluPerspective(…) 就可以根据输入生成一个透视投影矩阵。

而且在大多数情况下不需要了解具体的内幕算法也可以完成任务。

但是你不觉得,如果想要成为一个职业的图形程序员或游戏开发者,就应该真正降伏透视投影这个家伙么?我们先从必需的基础知识着手,一步一步深入下去(这些知识在很多地方可以单独找到,但我从来没有在同一个地方全部找到,但是你现在找到了)。

我们首先介绍两个必须掌握的知识。

有了它们,我们才不至于在理解透视投影变换的过程中迷失方向(这里会使用到向量几何、矩阵的部分知识,如果你对此不是很熟悉,可以参考可以找到一组坐标(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)是坐标系下表达一个向量和点的不同表达方式。

这里可以看出,虽然都是用代数分量的形式表达向量和点,但表达一个点比一个向量需要额外的信息。

透视投影的原理和实现

透视投影的原理和实现

透视投影的原理和实现透视投影的原理和实现摘要:透视投影是3D渲染的基本概念,也是3D程序设计的基础。

掌握透视投影的原理对于深⼊理解其他3D渲染管线具有重要作⽤。

本⽂详细介绍了透视投影的原理和算法实现,包括透视投影的标准模型、⼀般模型和屏幕坐标变换等,并通过VC实现了⼀个演⽰程序。

1 概述在计算机三维图像中,投影可以看作是⼀种将三维坐标变换为⼆维坐标的⽅法,常⽤到的有正交投影和透视投影。

正交投影多⽤于三维健模,透视投影则由于和⼈的视觉系统相似,多⽤于在⼆维平⾯中对三维世界的呈现。

透视投影(Perspective Projection)是为了获得接近真实三维物体的视觉效果⽽在⼆维的纸或者画布平⾯上绘图或者渲染的⼀种⽅法,也称为透视图[1]。

它具有消失感、距离感、相同⼤⼩的形体呈现出有规律的变化等⼀系列的透视特性,能逼真地反映形体的空间形象。

透视投影通常⽤于动画、视觉仿真以及其它许多具有真实性反映的⽅⾯。

2 透视投影的原理基本的透视投影模型由视点E和视平⾯P两部分构成(要求 E不在平⾯P上)。

视点可以认为是观察者的位置,也是观察三维世界的⾓度。

视平⾯就是渲染三维对象透视图的⼆维平⾯。

如图1所⽰。

对于世界中的任⼀点X,构造⼀条起点为E并经过X点的射线R,R与平⾯P的交点Xp即是X点的透视投影结果。

三维世界的物体可以看作是由点集合 { Xi} 构成的,这样依次构造起点为E,并经过点Xi的射线Ri,这些射线与视平⾯P的交点集合便是三维世界在当前视点的透视图,如图2所⽰。

图1 透视投影的基本模型图2 透视图成像原理基本透视投影模型对视点E的位置和视平⾯P的⼤⼩都没有限制,只要视点不在视平⾯上即可。

P⽆限⼤只适⽤于理论分析,实际情况总是限定P为⼀定⼤⼩的矩形平⾯,透视结果位于P之外的透视结果将被裁减。

可以想象视平⾯为透明的玻璃窗,视点为玻璃窗前的观察者,观察者透过玻璃窗看到的外部世界,便等同于外部世界在玻璃窗上的透视投影(总感觉不是很恰当,但想不出更好的⽐喻了)。

投影矩阵的推导

投影矩阵的推导

投影矩阵的推导(OpenGL D3D)OpenGL矩阵推导——模型视图变化在三维编程中,模型视图变换是从三维世界到二维屏幕中一个很重要的变换,但是这个变换往往很多人都不太理解,要么是事而非。

而这方面的文章不是太少就是讲的太浅没有真正的理解模型视图变换,本人在这个过程中曾经走过很多歪路,不过好在最终在自己的不懈努力下终于降伏了这只猛虎。

本人就以自己的理解,通过矩阵推导过程一步一步来了解模型视图变化,最后通过两个OpenGl的程序来进一步理解模型视图矩阵。

先从一个基本的模型视图—透视投影变换讲起。

透射投影是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume 以下简称CVV)中,待裁剪完毕后进行透视除法的行为。

透视投影变换是令很多刚刚进入3D图形领域的开发人员感到迷惑乃至神秘的一个图形技术。

其中的理解困难在于步骤繁琐,对一些基础知识过分依赖,一旦对它们中的任何地方感到陌生,立刻导致理解停止不前。

主流的3D APIs 都把透射投影的具体细节进行了封装,从而只需一个函数便可生成一个透射投影矩阵比如gluPerspective(),使得我们不需要了解其算法便可实现三维到二维的转化,然而实事是,一些三维图形或游戏开发人员遇到一些视图矩阵的问题往往会不知所措,比如视景体裁剪。

以下部分内容是从别处那转过来的,主要感谢Twinsen和一个叫丁欧南的高中生。

透视投影变换是在齐次坐标下进行的,而齐次坐标本身就是一个令人迷惑的概念,这里我们先把它理解清楚。

齐次坐标对于一个向量v以及基oabc,可以找到一组坐标(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)是坐标系下表达一个向量和点的不同表达方式。

矩阵论在Direct3D中三维坐标变换的运用

矩阵论在Direct3D中三维坐标变换的运用
旋转(Rotate):改变物体的姿态。
将图形绕x轴旋转角α的变换矩阵为:
将图形绕y轴旋转角α的变换矩阵为:
c)放缩(Scale)
放缩(Scale):改变物体的大小。
对图形作比较变换矩阵为:
a,e,i分别表示x,y,z的放大率,其坐标关系为:
当a,e,i均等于1时,则变换矩阵为:
这时T产生全比例变换,其中s为整个图形的放大率,当s﹤1时整个图形放大,当s﹥1时整个图形缩小。
上式便为视平面坐标系到屏幕坐标系的变换方程。
五、
通过系统地学习矩阵论的相关知识,本人结合计算机中的Direct3D技术的具体应用,分析了矩阵论在实际计算机图形学应用中的作用。通过学习我发现,矩阵论在计算机图形学中有非常广泛的应用,在二维、三维图形学应用有具有举足轻重的作用。矩阵论中前人总结的一些数学算法为计算机图形学的发展打下了基础。
);
绕Z轴旋转:
D3DXMATRIX *D3DXMatrixRotationZ(
D3DXMATRIX* pOut, //返回的结果
FLOAT Angle //旋转的弧度
);
绕指定轴旋转:
D3DXMATRIX *D3DXMatrixRotationAxis(
D3DXMATRIX *pOut,//返回的结果
CONST D3DXVECTOR3* pUp//设置方向“上”
);
可以看出,试图矩阵定义了摄像机在世界空间中的位置、观察点、方向“上”等信息。
定义投影矩阵:
D3DXMATRIX *D3DXMatrixPerspectiveFovLH(
D3DXMATRIX* pOut,//返回投影矩阵指针
FLOAT fovY,//定义镜头垂直观察范围,以弧度为单位

投影矩阵的计算过程

投影矩阵的计算过程

投影矩阵的计算过程投影矩阵的计算过程3d模型经过世界坐标变换、相机坐标变换后,下⼀步需要投影变换。

投影变换的⽬的就是要把相机空间转换到标准视图空间,在这个空间的坐标都是正规化的,也就是坐标范围都在[-1,1]之间,之所以转换到这个空间是为了后续操作更⽅便。

下⾯的讨论都是以列向量来表⽰,这样在变换操作时,采⽤的是矩阵左乘法,如果采⽤的是⾏向量的话,那就相反,矩阵右乘法即是向量在左边乘以变换矩阵。

采⽤哪种表⽰并不影响结果,只需要把该种表⽰下得出的变换矩阵转置⼀下,就是采⽤另外⼀种表⽰模式需要的结果。

常见的投影有两种,正交投影和透视投影,正交投影相对来说更简单,所以先来看看正交投影。

最简单的正交变换矩阵1 0 0 00 1 0 00 0 0 1这个正交变换是不可逆变换,变换后x和y保留,z变成了0,在实际应⽤中,更常见的情况是限定x、y、z在⼀定的范围内的进⾏投影变换,⽐如x[l,r],y[b,t],z[n,f]。

那么要把这段空间中的点变换到-1和1之间,只要完成两个变换,⾸先把坐标轴移到中⼼,然后进⾏缩放就可以了。

采⽤列向量的话,那就是缩放矩阵乘以平移矩阵。

2/(r-l) 0 0 0 1 0 0 -(r+l)/2 2/(r-l) 0 0 -(r+l)/(r-l)0 2/(t-b) 0 0 x 0 1 0 -(b+t)/2 = 0 2/(t-b) 0 -(t+b)/(t-b)0 0 2/(f-n) 0 0 0 1 -(n+f)/2 0 0 2/(f-n) -(f+n)/(f-n)0 0 0 1 0 0 01 0 0 0 1透视投影类⽐于我们⼈眼系统,看⼀个物体,会有远⼩近⼤的效果。

在转换到相机空间后,相机是这个空间的原点,和正交投影体是⼀个长⽅体或者⽴⽅体不同,透视投影体是⼀个锥体被近平⾯截取掉头部剩下的空间。

假定仍然采⽤上⾯的坐标表⽰。

在透视投影下,空间上⾯的任何⼀点P投影到近平⾯上某点q,通过三⾓⼏何学我们可以得到q x=p x*n/p z ,y点同理。

深入探索正交投影变换

深入探索正交投影变换

深入探索正交投影变换之前我们在《深入探索透视投影变换》以及《深入探索透视投影变换(续)》中研究了OpenGL、D3D以及M3G的透视投影变换的原理以及生成方法。

这些方法在当前的主流图形API 中得到了普遍使用。

但关于投影应用,还有一类经常使用的投影方式需要我们深入理解——正交投影,我们在本篇文章里面研究它(这里假设读者已经看过前两篇文章,并理解了绝大多数的理论,因为正交投影比透视投影的推导关系简单得多,因此我们的推导会非常得快,如果读者有任何的不解,请参考前两篇文章或者通过email联系我)。

在具体研究之前我觉得有必要把平面投影的分类简单介绍一下,目的是为了让大家有一个总体的认识,从而更好的理解这个知识体系。

请看下图:平面投影分为平行投影和透视投影两种类型,后者我们在前两篇文章中介绍了。

平行投影则是具有矩形观察体的投影方式(透视投影则是视锥观察体),它不会根据物体离视点的远近缩放物体(透视投影则会)。

平行投影可以分成侧投影和正交投影两种类型。

这两种类型如何区分呢?我们继续看图吧:上图中,v是投影平面,n是它的法线。

p和q是平面外两点,p’和q’分别是它们在平面上的投影点。

q的投影方向向量为Q = 单位化(q’-q),而p的投影方向向量为P = 单位化(p’-p),其中Q不平行于n而P平行于n,则q的投影叫做侧投影,而p的投影叫做正交投影。

正交投影是我们今天的研究对象。

实际上上面对平面投影的分类还可以继续向下细分,比如透视投影可以分为一灭点、二灭点以及三灭点透视投影。

侧投影则可以继续分为散点侧投、斜二轴侧投等等。

而正交投影则可以分成轴侧投影以及多视点正交投影等等。

如果读者对此感兴趣,可以参考相关的图形学教程。

接下来我们研究正交投影。

分别介绍OpenGL、D3D以及M3G的。

我们的环境约定(左右手坐标系、行列向量乘法、CVV范围)仍然尊重相应API自己的设置。

OpenGL正交投影变换下图是OpenGL的右手坐标系中观察空间的情形,我们看到的是正交投影的矩形观察体,原点是相机位置,n是近裁剪平面到相机平面的距离,f是远裁剪平面到相机平面的距离。

OpenGL学习脚印:投影矩阵的推导

OpenGL学习脚印:投影矩阵的推导

OpenGL学习脚印:投影矩阵的推导OpenGL学习脚印: 投影矩阵的推导写在前面本节内容翻译和整理自songho的博客《OpenGL Projection Matrix》内容,以供自己和初学者熟悉投影矩阵推导过程。

通过本节,你可以了解到:•投影矩阵计算的阶段•透视投影和正交投影的矩阵推导本节的要点就在于: 阅读时,自己拿笔推导一遍。

1.概览计算机屏幕是2维的,OpenGL渲染的3D场景必须以2D形式的图像投影到屏幕上。

GL_PROJECTION 矩阵就是用来设置投影变换的。

首先,它将所有顶点从眼坐标(照相机坐标)转换到裁剪坐标系下。

然后,这些裁剪坐标通过透视除法,即除以裁剪坐标中w分量,转换到归一化设备坐标系(NDC)。

一个由视锥裁剪的三角形因此,我们要记住,裁剪(视锥剔除frustum culling)和NDC转换都集成到了GL_PROJECTION 矩阵。

接下来的部分描述了怎么样通过left, right, bottom, top, near and far 这6个界限参数来构造投影矩阵。

注意:视锥剔除是在裁剪坐标系中进行的,并且恰好在透视除法之前进行。

裁剪坐标xc, yc 和 zc 通过与wc比较来进行测试。

如果某个坐标值比Wc小或者比Wc大,那么这个顶点将被丢弃。

然后,OpenGL会重新在裁剪进行的地方构造多边形的边缘。

补充内容:实际上,眼坐标系下坐标在乘以投影矩阵后,裁剪测试和透视除法都是由GPU来执行的。

而后面这两个过程处理的裁剪坐标系数据都是由投影矩阵变换的。

1. 裁剪测试也即视锥剔除-Wc < Xc,Yc,Zc < Wc2. NDC透视除法Xn = Xc / Wc Yn = Yc / Wc Zn = Zc / Wc这里需要注意的是,我们在构造16个参数的投影矩阵的同时,不仅要考虑到裁剪,还要考虑到透视除法的过程。

这样,最终的NDC坐标才会满足:-1 < Xn,Yn,Zn < 12.透视投影在透视投影中,在眼坐标下截头椎体(a truncated pyramid frustum)内的3D点被映射到NDC下一个立方体中;x坐标从[l,r]映射到[-1,1],y坐标从[b,t]映射到[-1,1],z坐标从[n,f]映射到[-1,1]。

透视投影变换的推导过程-3D基础知识

透视投影变换的推导过程-3D基础知识

透视投影变换的推导过程-3D基础知识感觉很多书上都没讲清楚透视投影变换的推导过程,自己推导了下,以前一直含糊的关于方形/非方形的视平面和屏幕的宽高比的问题也有了答案.本文组织如下:1.相机空间到视平面的变换2.视平面到屏幕的变换3.综合4.一般情形1.相机空间到视平面的变换* p (xc,0, zc)/ |/ |/ |X |/ |^ *p |(xp,0,zp)| / | || / | || / | |C(cam) |/ | |--------*----|----*------------->Z0 dx zc(X-Z平面的投影示图)a.透视投影一般的视景体为棱台,相机空间的物体会投影到视平面z=d,这里考虑左手坐标系,矩阵使用行优先方式。

如图所示,由相似三角形知识可知相机空间中的物体投影到视平面上的坐标为:xp = xc*(dx/zc)yp = yc*(dy/zc)其中,xc,yc,zc为相机空间坐标,xp,yp,zp为视平面坐标,dx,dy为x,y轴向的视距view distance,视平面到camera的距离,故相机空间投影到视平面上的矩阵Tcp为:|dx 0 0 0 ||0 dy 0 0 ||0 0 1 1 ||0 0 0 0 |(验证:T cp右乘点p(xc,yc,zc,1)得点p (xc*dx, yc*dy, zc, zc),转换为3D坐标为(xc*dx/zc, yc*dy/zc, 1),正确。

)*************************************************************** *****注:因为转换过程中点使用的是4D齐次坐标,所以最后需转换为3D坐标。

4D齐次坐标(x,y,z,w)转换为3D坐标的方法为除以w分量,即对应3D坐标为(x/w,y/w,z/w)。

*************************************************************** *****考虑dx/zc和dy/zc项,如果dx != dy,则投影后x,y的比例会发生变化(原因:投影前坐标比例为xc/yc,投影后为xp/yp = xc*(dx/zc)/yc*(dy/zc) = xc*dx/yc*dy),从而投影后的图像的x,y比例会发生变形。

透视投影的详细解释(转载)

透视投影的详细解释(转载)

透视投影的详细解释(转载)本⽂乃<投影矩阵的推导>译⽂,原⽂地址为:译者: 流星上的潴如需转载,请注明出处,感谢!在3D图形程序的基本矩阵变换中,投影矩阵是其中⽐较复杂的。

平移和缩放浏览⼀下就能理解,旋转矩阵只要掌握了三⾓函数知识也可以理解,但投影矩阵有点棘⼿。

如果你曾经看过投影矩阵,你会发现你的常识不⾜以告诉你它是怎么来的。

⽽且,我在⽹上还未看到许多关于如何推导投影矩阵的教程资源。

本⽂的话题就是如何推导投影矩阵。

对于刚刚开始接触3D图形的⼈,我应该指出,理解投影矩阵如何推导可能是我们对于数学的好奇⼼,它不是必须的。

你可以只⽤公式,并且如果你⽤像Direct3D那样的图形API,你甚⾄都不需要使⽤公式,图形API会为你构建⼀个投影矩阵。

所以,如果本⽂看起来有点难,不要害怕。

只要你理解了投影矩阵做了什么,你没必要在你不想的情况下关注它是怎么做的。

本⽂是给那些想了解更多的程序员的。

概述: 什么是投影?计算机显⽰器是⼀个⼆维表⾯,所以如果你想显⽰三维图像,你需要⼀种⽅法把3D⼏何体转换成⼀种可作为⼆维图像渲染的形式。

那也正是投影做的。

拿⼀个简单的例⼦来说,⼀种把3D对象投影到2D表⾯的⽅法是简单的把每个坐标点的z坐标丢弃。

对⽴⽅体来说,看上去可能像图1:图1: 通过丢弃Z坐标投影到XY平⾯当然,这过于简单,并且在⼤多数情况下不是特别有⽤。

⾸先,根本不会投影到⼀个平⾯上;相反,投影公式将变换你的⼏何体到⼀个新的空间体中,称为规范视域体(canonical view volume),规范视域体的精确坐标可能在不同的图形API之间互不相同,但作为讨论起见,把它认为是从(-1, -1, 0)延伸⾄(1, 1, 1)的盒⼦,这也是Direct3D中使⽤的。

⼀旦所有顶点被映射到规范视域体,只有它们的x和y坐标被⽤于映射到屏幕上。

这并不代表z坐标是⽆⽤的,它通常被深度缓冲⽤于可见度测试。

这就是为什么变换到⼀个新的空间体中,⽽不是投影到⼀个平⾯上。

D3D,OPENGL视点变换矩阵,投影矩阵(clip space)的推导过程

D3D,OPENGL视点变换矩阵,投影矩阵(clip space)的推导过程

D3D,OPENGL视点变换矩阵,投影矩阵(clip space)的推导过程此处推导D3D的变换矩阵(采用行向量,行主序存储,右乘矩阵),然后通过调整得出OPENGL中的变换矩阵1. 视点变换矩阵的推导。

根据给定的眼睛位置(position),朝向(orientation)来计算最终的视点变换矩阵。

投影矩阵的计算见Frustum类计算过程大致如下:设Q代表从世界空间坐标系到眼睛空间坐标系的变换矩阵,V代表一个点故VQ=VMT.其中T:从世界空间坐标系到眼睛空间坐标系的平移变换矩阵,M:从世界空间坐标系到眼睛空间坐标系的旋转变换矩阵。

则Q1-代表视点变换矩阵Q1-=MT1-= T1-M1-由于M是正交矩阵,故V=Q1-= T1-M T其中M=[Rx Ry Rz 0], T= [1 0 0 0][Ux Uy Uz 0] [0 1 0 0][Dx Dy Dz 0] [0 0 1 0 ][0 0 0 1] [Tx Ty Tz 1 ]故V=Q1-= [1 0 0 0] * [Rx Ux Dx 0][0 1 0 0] [Ry Uy Dy 0][0 0 1 0] [Rz Uz Dz 0][-Tx –Ty –Tz 1] [0 0 0 1]= [ Rx Ux Dx 0 ][ Ry Uy Dy 0 ][ Rz Uz Dz 0 ][ Wx Wy Wz 1 ]其中W = - Pos* M T对于OPENGL,则有:V=Q1-=M T T1-其中M=[Rx Ux -Dx 0][Ry Uy -Dy 0][Rz Uz -Dz 0][0 0 0 1]T= [1 0 0 Tx][ 0 1 0 Ty][0 0 1 Tz][0 0 0 1 ]故V=Q1 =[Rx Ry Rz Wx][Ux Uy Uz Wy][-Dx –Dy –Dz Wz][0 0 0 1]其中W = -M T* Pos2. 透视投影(perspective projection)矩阵的推导假设(X,Y,Z,1)为一个点,投影后的点为(Xp,Yp,Zp,1)则根据相似三角形原理,有:Xp/X=Yp/Y=N/Z所以:Xp=N*X/ZYp=N*Y/ZZp=N故投影变换可以表示为齐次坐标形式:(Xp,Yp,Zp,1)=(X,Y,Z,Z/N)对于X和Y :在进行上一步变换后,还要进一步做裁剪变换,即将投影后的坐标映射为[-1,1].即:(X*N/Z,Y*N/Z) : ([l,r],[b,t]) ([-1,1],[-1,1])即:(X*N/Z-l)/(r-l)=(s+1)/2由此可以得到:对于Z,变换稍微复杂一些。

投影矩阵

投影矩阵

视锥就是场景中的一个三维空间,它的位置由视口的摄像机来决定。

这个空间的形状决定了摄像机空间中的模型将被如何投影到屏幕上。

透视投影是最常用的一种投影类型,使用这种投影,会使近处的对象看起来比远处的大一些。

对于透视投影,视锥可以被初始化成金字塔形,将摄像机放在顶端。

这个金字塔再经过前、后两个剪切面的分割,位于这两个面之间的部分就是视锥。

只有位于视锥内的对象才可见。

视锥由凹视野(在上图中,变量投影矩阵是一个典型的缩放和透视矩阵。

投影变换将视锥变换成一个直平行六面体的形状。

因为视锥的近处比远处小,这样就会对靠近摄像机的对象起到放大的作用,也就将透视应用到了场景当中。

在视锥中,摄像机与空间原点间的距离被定义为变量视矩阵将摄像机放置在场景的原点。

又因为投影矩阵需要将摄像机放在将两个矩阵相乘,得到下面的矩阵:下图显示了透视变换如何将一个视锥变换成一个新的坐标空间。

注意:锥形体变成了直平行六面体,原点从场景的右上角移到了中心。

在透视变换中,这个矩阵基于一定的距离(这个距离是从摄像机到邻近的剪切面)对对象进行平移和旋转,但是它没有考虑到视野(在这个矩阵中,在程序中,使用视野角度来定义x和y缩放系数比使用视口的水平和垂直尺寸(在摄像机空间中)并不方便多少。

下面两式使用了视口的尺寸,并且与上面的公式相等:在这些公式中,Zn表示邻近的剪切面的位置,变量Vw和Vh表示视口的高和宽。

这两个参数与D3DVIEWPORT2结构中的dwWidth和dwHeight成员相关。

不管你使用那个公式,将同世界和视变换一样,可以调用下面的D3DMATRIX ProjectionMatrix(const float near_plane,// distance to near clipping planeconst float far_plane,// distance to far clipping planeconst float fov_horiz,// horizontal field of view angle, in radiansconst float fov_vert)// vertical field of view angle, in radians {float h, w, Q;w = (float)cot(fov_horiz*0.5);h = (float)cot(fov_vert*0.5);Q = far_plane/(far_plane - near_plane);D3DMATRIX ret = ZeroMatrix();ret(0, 0) = w;ret(1, 1) = h;ret(2, 2) = Q;ret(3, 2) = -Q*near_plane;ret(2, 3) = 1;return ret;} // end of ProjectionMatrix()一旦创建完了矩阵,你需要调用一个顶点经过世界、观察和投影变换之后,下图展示了一个不适合的投影矩阵,和一个经过缩放的适合的矩阵:在前面的矩阵中,所有的变量都被假定为非零。

透视投影的坐标转换与数学推导

透视投影的坐标转换与数学推导

透视投影的坐标转换与数学推导坐标转换管线在处理顶点数据时需要经过多个坐标系的转换。

1.通过model与view矩阵先将其变换到世界坐标系中,再将其变换到观察坐标系中。

从⽽⽅便后续处理。

2.经透射投影,将3D坐标映射到视平⾯,完成从3D到2D的变换,从⽽在后续可转换为在屏幕显⽰的2D坐标。

3.透射投影将顶点转换到了单位⽴⽅体中,变换到标准化设备坐标系。

4.⽽标准化设备坐标系中的物体常常会产⽣形变,为恢复物体原⽐例,将其进⾏视⼝变换,转换到最后显⽰的屏幕坐标系中。

以上为顶点在坐标转换中的⼤致流程,其中包含的很多细节部分会在下⾯结合透射投影进⾏详细分析。

逻辑分析图 1 图 2 图 3 图41.转换:我们输⼊在程序中的坐标都是3D,⽽最终显⽰在屏幕上的只能是2D。

所以可想⽽知,需要⼀个过程来将3D坐标映射到我们的2D视平⾯上。

只有这样我们才能通过显⽰器去观看。

2.观察:如上述图1,我们在观察⾯上所观察到的正是观察点E与物体实际坐标的连线在视平⾯P上的交点,其⽐例也可形成近⼤远⼩的现实感。

图2可直观的感受。

3.问题:根据学过的知识,显然这⼀交点可以很轻松的通过相似三⾓形来求得。

但问题是,我们需要获得多⼤范围内的物体?即限定观察空间。

不在观察空间内的物体⼜该怎样去处理?即裁剪。

4.观察空间:设定近平⾯,远平⾯,和观察⾓度,来得到⼀个视椎体(frustum)。

⽽我们也常常将近平⾯作为视平⾯。

如图3。

5.裁剪:裁剪掉视锥体以外的顶点,只保留以内的。

若直接对视锥体裁剪,因平⾯的倾斜也会导致计算量过⼤,所以采⽤将其映射到单位⽴⽅体中(CVV),此时都为垂直平⾯,并且在映射过程中,顶点与视锥体的关系不变,在视锥体外的仍然在视锥体外。

裁剪时只需判定⼀个坐标即可,⼤⼤减少了计算量。

如图4。

6.恢复:但是在映射到CVV的时候,顶点间的⽐例产⽣了变化,物体常常产⽣形变,所以在映射到屏幕坐标系时,必须对其进⾏⽐例恢复。

采⽤的⽅法是:将近平⾯(即视平⾯)的宽⾼⽐例⼀开始就调整为与视⼝宽⾼⽐相同。

透视投影,与Z-BUFFER求值

透视投影,与Z-BUFFER求值
以下描述z buffer计算以及perspective projection matrix原理。
假设坐标在 world space 是 Pw = {Xw,Yw,Zw}
经过camera space transform 得到Pe = {Xe,Ye,Ze}
然后经过project transform 转为 device space,这里假设转为 Zp 范围 [-1,1](OPENG的Z BUFFER)
也就是说,不管A和B是什么,在Z BUFFER中的数值,总是和物体顶点在camera space中的 -1/Ze 成线性的关系。 我们要做的就是求A 和B。求A和B,我们利用以下条件:当Ze = far 时, Zp = 1当Ze = near时,Zp = -1(在OPENGL下是这样。在D3D下是Zp =0)这实际是个2元一次方程。有了两个已知解,可以求出A和B。OPENGL下,A = 2nf/(f-n), B = (f+n)/(f-n)
考虑Xp = (Xep - left)*2/(right-left) -1 (Xep = -n* Xe/Ze)Yp = (Yep - left)*2/(right-left) -1 (Yep = -n* Ye/Ze)Zp = A* 1/Ze + B
为了得到4X4 MATRIX,我们需要把(Xp,Yp,Zp,1)转为齐次坐标 (-Xp*Ze, -Yp*Ye, -Zp*Ze, -Ze) 。然后由矩阵乘法公式和上面已知坐标,就可以得到PROJECTION MATRIX。
这样一来,我们就知道Z BUFFER的数值如何求得。先把物体顶点世界坐标Pw变换到camera space中得到Pe。然后再经过透视投影变换,求得Ze-&gt;Zp的数值。把这个数值填入Z buffer,就是显卡用来比较哪个像素在前,哪个像素在后的依据了。这也就是为什么near和far设置不合适的时候,很容易发生z fighting。一般情况下,离屏幕很近的一段距离,已经用掉了90%的z 浮点精度。在用于渲染视角里中远距离的场景时,深度的判别只靠剩下的10%精度来进行。具体推导可以看看http://www.cs.kuleuven.ac.be/cwis/research/graphics/INFOTEC/viewing-in-3d/node8.html

DirectX

DirectX

D3DXMatrixPerspectiveFovLHDirectX中投影变换D3DXMatrixPerspectiveFovLH()其实产生的变换矩阵不是将3D物体转换为2D平面画面的变换。

实际上是把3D世界的物体变换到(1,1,0) (-1,1,0) (-1,-1,0) (1,-1,0) (1,1,1) (-1,1,1) (-1,-1,1) (1,-1,1)这个小盒子中。

在Jim Adams 的著作<Role playing games with DriectX 8.0>和Frank Luna 的著作中<Introduction to 3D Game Programming with DirectX9.0>都把这个变换矩阵讲成从3D到2D的变换。

实际上在DirectX中3D到2D的变换是由SDK 自己完成的。

而我们要做的是把3D世界变换到上面那个小盒子中。

这个变换矩阵是投影变换的预变换。

在DirectX中,把视口的高作为3D世界里面的长度:2.0f来使用的,一个视点观察世界的视野范围在Y轴上无论什么情况下都是-1.0f到1.0f(这一点在后面来证明)。

把视口的高作为y轴,顶端坐标为(x,1),底端坐标为(x,-1)。

视口:在窗体中显示3D的矩形范围,可以通过D3DDevice的SetViewPort()来设置大小,默认的大小为窗体的大小。

变换的过程就是把点的向量乘以变换矩阵,可以得到这个点在新坐标系的对应向量,在投影变换矩阵中Z轴的值落在0~1之内,也就是说3D世界里所有的点都会被投影到以上描述的小盒子中。

我们用函数D3DXMatrixPerspectiveFovLH来获得该“投影变换”矩阵。

D3DXMA TRIX * D3DXMatrixPerspectiveFovLH(D3DXMA TRIX *pOut,FLOAT fovy,FLOAT Aspect,FLOAT zn,FLOAT zf);其中参数fovy为y轴上的视角,Aspect为高宽比,zn为近裁面,zf为远裁面。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档