D3D透视投影矩阵推导

合集下载

摄像机矩阵和投影矩阵推导

摄像机矩阵和投影矩阵推导

坐标系旳转换和矩阵
后续旳内容主要统计World坐标系转换之后旳Camera 坐标系,Projection坐标系旳转换。
接下来统计旳转换矩阵推导,是用DirectX来举例。实 际上,这些推导过程在OpenGL上也是一样旳,假如 有差别,也是某些数值上旳细微差别,例如DirectX旳 远近裁剪面定为[0~1],而OpenGL旳定为[-1~1]。
z
向量B
向量A x
减法
• 平移向量A到
向量A’,因为是
y
A-B,所以连接B
旳尾部到A’旳尾部,
向量A’
z 向量C
向量A
使是A-B
• 平移向量B也能得到一样旳成果
向量旳基本运算:点乘
Dot Product,又叫点乘或点积,定义为:
如上式所示,点乘旳成果是一种标量。背面我们将要 证明该标量和 有关,其中 是这两个向量旳夹角, 也即是说,从两个向量点乘旳成果能得出它们之间旳 夹角。这就是点乘旳价值所在。
阐明
写统计最艰难莫过于公式编辑了,每一种数学式子, 都是从Word里面用公式编辑器编辑好,再复制过来, 更悲剧旳事情是PPT貌似不支持公式,它把复制过来 旳公式直接变成图片了。
可见我是多用心。
点和(方向)向量
数值上,都是用{x,y,z}表达。 前者表达位置,后者表达方向。
因表征意义不同,图形库一般以Point类和Vector类体 现两者,但它们在数值层面是一致旳。
Model坐标系
模型坐标系,也叫Local坐标系。例如我们在 3DMax,MAYA等建模工具中建立我们旳人物模型时, 模型中旳顶点坐标值就是Model坐标系旳值。设想我 们有多种人物模型,那么每一种模型都有属于自己旳 Model坐标系。

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)是坐标系下表达一个向量和点的不同表达方式。

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

投影矩阵的推导

投影矩阵的推导

投影矩阵的推导(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点同理。

透视投影的原理和实现

透视投影的原理和实现

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

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

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

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

正交投影多用于三维健模,透视投影则由于和人的视觉系统相似,多用于在二维平面中对三维世界的呈现。

透视投影(PerspectiveProjection)是为了获得接近真实三维物体的视觉效果而在二维的纸或者画布平面上绘图或者渲染的一种方法,也称为透视图[1]。

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

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

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

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

视平面就是渲染三维对象透视图的二维平面。

如图1所示。

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

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

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

P无限大只适用于理论分析,实际情况总是限定P为一定大小的矩形平面,透视结果位于P之外的透视结果将被裁减。

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

深入探索正交投影变换

深入探索正交投影变换

深入探索正交投影变换之前我们在《深入探索透视投影变换》以及《深入探索透视投影变换(续)》中研究了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

关于裁剪空间与投影变换矩阵的推导

关于裁剪空间与投影变换矩阵的推导

关于裁剪空间与投影变换矩阵的推导再看irrlicht的数学库中matrix4实现时,对这个透视投影变换矩阵的公式⼗分疑惑,经过艰苦的奋⽃终于搞清楚是怎么⼀回事在这⾥和⼤家分享⼀下irrlicht中使⽤的透视矩阵是DirectX风格的,但个⼈偏好于OpenGL的风格所以下⾯的实现将会使⽤OpenGL的风格实现。

注意:这⾥使⽤的是⽔平视⾓和Y:X,DirectX中使⽤的是垂直视⾓和X:Yinline void SetPerspectiveFovMatrixLH( f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar){Assert( Equal( aspectRatio, 0.f ) ); //divide by zeroAssert( Equal( fieldOfViewRadians, 0.f ) ); //divide by zeroAssert( Equal( zNear, zFar ) ); //divide by zerof32 wc = 1 / tan( fieldOfViewRadians / 2 );f32 hc = wc / aspectRatio;m_[0][0] = wc;m_[0][1] = 0;m_[0][2] = 0;m_[0][3] = 0;m_[1][0] = 0;m_[1][1] = hc;m_[1][2] = 0;m_[1][3] = 0;m_[2][0]= 0;m_[2][1]= 0;m_[2][2] = ( zFar + zNear ) / ( zFar - zNear );m_[2][3] = 1.0f;m_[3][0] = 0;m_[3][1] = 0;m_[3][2] = 2 * zNear * zFar / ( zNear - zFar );m_[3][3] = 0;}这⾥是我写的透视矩阵的⼀段代码,得到的矩阵式这样⼦的:w 0 0 00 h 0 00 0 (f+n)/(f-n) 10 0 2nf/(n-f) 0实际上这个叫透视矩阵的东西实现的不仅仅是透视功能,如果要实现透视功能实际上的矩阵式这样⼦的:那多出来的这部分:是⽤来⼲什么的呢,实际上”透视矩阵“的功能不仅仅是透视,还有⼀个裁剪的功能,它可以把不在视景体内的顶点裁剪掉,则多出来的部分就是⽤来进⾏裁剪的。

三维坐标变换矩阵公式推导

三维坐标变换矩阵公式推导

三维坐标变换矩阵公式推导好的,以下是为您生成的文章:咱们来聊聊三维坐标变换矩阵这个听起来有点复杂,但其实也挺有趣的玩意儿。

想象一下,你正在一个三维的空间里玩耍,就像在一个巨大的积木世界里。

每个点都有自己的位置,就像每块积木都在它该在的地方。

那什么是三维坐标变换矩阵呢?其实啊,它就像是一个神奇的魔法工具,可以把这些点的位置进行各种奇妙的变化。

比如说,我们先从简单的平移开始。

假设我们有一个点 P(x, y, z),要把它沿着 x 轴平移 a 个单位,沿着 y 轴平移 b 个单位,沿着 z 轴平移 c 个单位,那新的点 P'(x', y', z') 就可以通过这样的公式算出来:x' = x + a,y' = y + b,z' = z + c。

如果把这个写成矩阵的形式,那就是:\[\begin{pmatrix}1 & 0 & 0 & a \\0 & 1 & 0 & b \\0 & 0 & 1 & c \\0 & 0 & 0 & 1\end{pmatrix}\times\begin{pmatrix}x \\y \\z \\1\end{pmatrix}=\begin{pmatrix}x + a \\y + b \\z + c \\1\end{pmatrix}\]这是不是有点像给点穿上了一双会带着它到处跑的魔法鞋?再来说说旋转。

就拿绕 x 轴旋转来说吧。

假设旋转角度是θ,那点P(x, y, z) 旋转后的点 P'(x', y', z') 可以这样计算:x' = x,y' = ycosθ - zsinθ,z' = ysinθ + zcosθ。

写成矩阵形式就是:\[\begin{pmatrix}1 & 0 & 0 & 0 \\0 & cosθ & -sinθ & 0 \\0 & sinθ & cosθ & 0 \\0 & 0 & 0 & 1\end{pmatrix}\times\begin{pmatrix}x \\y \\z \\1\end{pmatrix}=\begin{pmatrix}ycosθ - zsinθ \\ysinθ + zcosθ \\1\end{pmatrix}\]这就好像给点装上了一个会旋转的小陀螺,让它在空间里转圈圈。

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