openGL投影矩阵原理及数学推导
- 格式:doc
- 大小:361.00 KB
- 文档页数:7
glm 四元数转换矩阵-概述说明以及解释1.引言1.1 概述四元数(Quaternion)是数学中的一种扩展复数,广泛应用于3D计算机图形学和空间几何运算等领域。
它由一个实部和三个虚部组成,具有一些独特的性质和优点。
在图形学中,四元数被用于表示和计算物体的旋转,相比其他表示旋转的方法,如欧拉角和旋转矩阵,四元数具有更简洁和高效的计算方式。
本文将首先介绍球面线性插值(Spherical Linear Interpolation, 简称SLERP)的概念及其在计算机图形学中的应用。
接下来,我们将详细探讨四元数的定义和性质,包括四元数的运算法则、单位四元数的特点等。
最后,我们将重点讲解四元数与旋转矩阵之间的相互转换关系,包括如何将一个旋转矩阵转换为对应的四元数表示,以及如何从四元数恢复出旋转矩阵。
通过深入理解四元数与旋转矩阵之间的转换关系,我们可以更好地理解和应用四元数在3D图形学中的作用。
对于计算机图形学从业者来说,这是一个非常重要的基础知识。
此外,我们还将展望四元数在虚拟现实、计算机动画等领域的应用前景,并提出相关讨论和建议。
通过阅读本文,读者将能够理解四元数转换矩阵的原理和算法,并能够应用于实际问题中。
无论是从事计算机图形学研究还是从事相关行业工作的人士,本文的内容都将对他们的工作产生积极的影响和帮助。
总结起来,本文旨在为读者提供一份系统而全面的关于glm四元数转换矩阵的学习材料,并希望能够激发更多人对这一领域的兴趣和研究。
1.2文章结构文章结构部分的内容可以写成以下样式:2. 正文2.1 球面线性插值2.2 四元数的定义和性质2.3 四元数到旋转矩阵的转换在正文部分,我们将着重介绍GLM(OpenGL 数学库)中的四元数转换矩阵的相关知识。
首先,我们将会详细讨论球面线性插值算法的原理和应用,以便更好地理解四元数和矩阵之间的转换关系。
接下来,我们将会介绍四元数的定义和性质。
四元数是一种复数的扩展形式,具有独特的性质和运算规则。
OpenGL学习笔记:三维数学基础(⼀)坐标系、向量、矩阵接触OpenGL和计算机图形学有⼀段时间了,⼀直想写⼀点东西,记录⾃⼰的学习历程,或许也能够为有意愿向计算机图形学发展的菜鸟们提供⼀条捷径。
闲话不多说,本章主要介绍计算机图形学中三维数学的⼀些基础知识,主要包括2D、3D笛卡尔坐标系,向量、矩阵的数学和⼏何意义以及公式。
由于篇幅限制,其中的推导过程本⽂不作叙述,感兴趣的读者可以去看《3D数学基础+图形与游戏开发》,已上传,链接地址在本⽂末尾。
⼀、计算机图形学计算机图形学(Computer Graphics)是⼀种使⽤数学算法将⼆维或三维图形转化为计算机显⽰器的栅格形式的科学。
其⼴泛应⽤于游戏、动画、仿真、虚拟现实(VR)、增强现实(AR)等领域。
在数学之中,研究⾃然数和整数的领域称为离散数学,研究实数的领域称作连续数学。
在计算机图形学中,为虚拟世界选择度量单位的关键是选择离散的精度。
⼀种错误的观点认为short、int是离散的,⽽float、double是连续的,⽽事实上,这些数据类型都是离散的。
于是,计算机图形学有如下准则:计算机图形学第⼀准则:近似原则——如果它看上去是对的,它就是对的。
⼆、笛卡尔坐标系2D笛卡尔坐标系是⼀个精确定位点的框架。
2D坐标的标准表⽰法是(x,y),相信⼤家初中都学过。
⼀般,标准的笛卡尔坐标系是x轴向右,y轴向上。
⽽计算机图形学中的屏幕坐标往往是x轴向右,y轴向下。
如图1所⽰。
图1:2D笛卡尔坐标系和2D屏幕坐标系3D笛卡尔坐标系类似,增加了第三个维度,z轴。
3D坐标系分为完全不同的2种坐标系,左⼿坐标系和右⼿坐标系。
判断⽅法为,左⼿坐标系:伸出左⼿,让拇指和⾷指成“L”形,⼤拇指向右,⾷指向上,其余⼿指指向前⽅。
此时,拇指、⾷指和其余三指分别代表x、y、z轴的正⽅向。
右⼿坐标系,相同,只是把左⼿换成右⼿。
如图2所⽰。
图2:左⼿坐标系与右⼿坐标系其中左⼿坐标系⼴泛应⽤于计算机图形学、D3D之中,⽽右⼿坐标系⼴泛应⽤于OpenGL、线性代数、3DSMax之中。
投影矩阵的推导(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)是坐标系下表达一个向量和点的不同表达方式。
OpenGL空间(坐标系)变换⽹友的《3D图形学的学习策略》⼀⽂使我深受启发,在图形学以及openGL学习⽅⾯给了我很有价值的指导性意见,在此对前辈们的不吝赐教表⽰感激,谢谢你们的⽆私分享。
如⽂章所说,API是⼯具,不是本质,OpenGL/Direct3D的本质是图形学,⽽不是OpenGL/Direct3D的本⾝,API的本⾝只是⼀些Interface⽽已。
最重要的,最根本的是,你要明⽩这些API背后的图形学的原理---因为那才是根本中的根本。
其实很多事情,包括学习也涉及到⽣活,只有抓住了本质,才能体会到其中的真谛。
带着这种希望探究本质的学习⽅法,结合图形学原理,通过阅读书⽬和⽹友们的⽂章,我对OpenGL⼏何空间变换进⾏了总结性的学习。
OpenGL处理管线的⽬的是将对象的三维描述转换为可以显⽰的⼆维图像。
为了完成这个从三维到⼆维的转换,OpenGL 使⽤了多个空间(坐标系),每个空间完成特定的任务,从⼀个空间到另⼀个空间需要进⾏空间转换。
理解OpenGL所使⽤的各种空间以及它们间的变换是⾮常重要的。
如上图所⽰,openGL中使⽤的空间依次是:对象空间、世界空间、视点空间、裁剪空间、归⼀化设备空间、窗⼝空间、屏幕空间。
结合⾃⼰的理解,就每个空间完成的基本任务和空间的变换关系,总结如下。
对象空间。
对象空间中完成的最⼤任务是对象建模,三维对象的属性,包括顶点位置和表⾯法线等是在这个空间内指定的。
这个空间的坐标原点⼀般在对象上,有时候也在其他地⽅,主要是为了建模⽅便。
每⼀个对象都有⼀个⾃⼰的对象空间。
就openGL⽽⾔,我⽬前还没有接触到建⽴很复杂模型的应⽤,建模⼀般在其他地⽅如3DMAX中完成,然后读⼊openGL进⾏处理。
世界空间。
对象空间之后是世界空间,我理解为世界坐标系是固定不变的。
世界空间主要是对三维场景进⾏描述,就是把已经建⽴的各种对象摆放在三维空间中,空间的转换是通过模型变换完成的。
可以通过平移、旋转、⽐例缩放等把对象摆放在需要的位置,就好像买好家具以后设计房间布局⼀样。
OpenGL图形变换OpenGL图形软件包是为三维应用设计的,其中包含了大量的有关三维变换的操作,二维变换则可以看作是三维变换的特例。
OpenGL中常用的变换包括模型视图变换、投影变换和视见区变换。
一、矩阵堆栈在计算机图形学中,所有的变换都是通过矩阵乘法来实现的,即将三维形体顶点构成的齐次坐标矩阵乘以三维变换矩阵就得到了变换后的形体顶点的齐次坐标矩阵,这样只要求出形体的三维变换矩阵,就可以得到变换后的形体。
在OpenGL中,对象的坐标变换也是通过矩阵来实现的。
OpenGL中包含了两个重要的矩阵:模型视图矩阵和投影矩阵,其中模型视图矩阵用于物体的模型视图变换,投影矩阵用于投影变换。
一般来说,在进行矩阵操作之前,需要指定当前操作的矩阵对象,这可以使用函数:glMatrixMode(GLenum mode);定义。
其中当mode取GL_MODELVIEW时,表示对模型视图矩阵进行操作;当mode取GL_PROJECTION时表示对投影矩阵进行操作,并且一旦设置了当前操作矩阵,它就将保持为当前的矩阵对象,直到再次调用函数glMatrixMode修改它为止。
默认情况下,系统处理的当前矩阵是模型视图矩阵。
OpenGL为模型视图矩阵和投影矩阵各维护着一个“矩阵堆栈”,其中堆栈的栈顶矩阵就是当前的模型视图矩阵或投影矩阵。
在调用变换函数的时候,系统自动计算变换函数对应的变换矩阵与当前操作的矩阵堆栈栈顶矩阵的乘积,并置为栈顶矩阵,绘制图形时使用栈顶矩阵作为图形的变换矩阵。
矩阵堆栈主要用来保存和恢复矩阵的状态。
OpenGL中利用函数:void glPushMatrix(void);void glPopMatrix(void);实现矩阵堆栈的操作。
其中函数glPushMatrix将当前矩阵堆栈的栈顶矩阵复制一个,并将其压入当前矩阵堆栈,以保存当前变换矩阵。
函数glPopMatrix用于将当前矩阵堆栈的栈顶矩阵弹出,这样,堆栈中的下一个矩阵变为栈顶矩阵(当前变换矩阵),用来恢复当前变换矩阵原先的状态。
Opengl_10_透视投影1,We have finally reached the item that represents 3D graphics best - the projection from the 3D world on a 2D plane while maintaining the appearance of depth. A good example is a picture of a road or railway-tracks that seem to converge down to a single point far away in the horizon.通过在保留物体深度⽴体感的前提下将3d世界的物体投影到2d平⾯上最优化显⽰3D图形。
2,对图形的透视变换需要提供四个参数:1.屏幕宽⾼⽐:矩形屏幕的宽⾼⽐例是投影的⽬标;2.垂直视野:相机窗⼝看向3d世界的垂直⽅向上的⾓度;3.Z轴近平⾯的位置:近平⾯⽤于将离相机太近的物体裁剪掉;4.Z轴远平⾯的位置:远平⾯⽤于将离相机太远的物体裁剪掉;屏幕宽⾼⽐是⼀个必要的参数,因为我们要在⼀个宽⾼相等的单位化的盒⼦内展⽰所有的坐标系,⽽通常屏幕的宽度是⼤于屏幕的⾼度的,所以需要在⽔平⽅向上的轴线上布置更加密集的坐标点,竖直⽅向上相对稀疏。
这样经过变换,我们就可以在保证看到更宽阔屏幕图像的需求下,根据X轴在单位盒⼦空间内的⽐例,在X⽅向上添加更多的X坐标。
垂直视野(The vertical field of view)让我们可以(放⼤和缩⼩zoom in and out)3D世界。
左边的图⽚中相机的视⾓较⼤⽽在屏幕上物体看上去应该会较⼩;右边的视⾓较⼩⽽物体看上去应该会更⼤。
α > β, L2 > L1这是由于相机的位置导致的效果,有点违背直觉,(同样的物体咋就看上去⼀个⼤⼀个⼩了)。
左边的相机靠近投影屏幕使视⾓变⼤⽽右边的相机远离屏幕视⾓变⼩。
openGL投影矩阵
概述
显示器是2d的。
3d场景需要转换为2d图像才能显示在屏幕上。
投影矩阵(GL_PROJECTION)用于完成这个工作。
投影矩阵将观察坐标(eye coordinates)转换成裁剪坐标(clip coordinates)。
然后,裁剪坐标被除以w,转换为规范化的设备坐标(NDC)。
需要记住的一点是,裁剪操作和规范化都由投影矩阵(GL_PROJECTION)完成。
下面介绍如何用6个参数(left,right,bottom,top,near,far)构建投影矩阵。
裁剪(clipping)操作是在裁剪坐标上进行的,安排在透视除法执行之前。
裁剪坐标xc,yc,zc同wc比较,若每个分量都落在(-wc,wc)外,那么此坐标将被裁剪掉。
在透视投影中,3d场景中的点(观察坐标)从平截头体中映射到正方体(NDC)中;x坐标从[l,r]映射到[-1,1],y坐标从[b,t]映射到[-1,1],z坐标从[n,f]映射到[-1,1]。
注意到,观察坐标系是右手系,规范设备坐标系是左手系。
这就有,在观察坐标系中,摄像机朝向沿着-z,而在NDC中,方向沿着z。
由于glFrustum()只接受正参数,所以构造投影矩阵的时候要变号。
openGL中,3d场景中,观察坐标系下的点被投影到近投影面。
下图展示了观察坐标系点(xe,ye,ze)投影到近投影面上的点(xp,yp,zp)。
从Top View of Projection看,xe投影到xp,根据等比性质:
从Side View of Projection看,yp计算类似:
注意到,xp和yp依赖于-ze,这一点要引起重视。
在观察坐标被投影矩阵转换为裁剪坐标后,裁剪坐标仍然是同质坐标。
在规范化阶段执行透视除法变为规范设备坐标(NDC)。
因此,可以将wc的值定为-ze。
投影矩阵最后一行为(0,0,-1,0)
下一步,将xp,yp映射到xn,yn,此为线性映射[l,r]=>[-1,1],[b,t]=>[-1,1]:
将xp,yp带入上面结果:
对比(xc/wc,yc/wc)wc=-ze得出上式括号中分别为xc,yc。
由上式的结果可以观察出投影矩阵的第一行、第二行值:
现在只差第三行。
Ze总是映射到-n,但是又需要有区分的z值用于裁剪和深度测试,也需要能够实现逆变换。
我们看到,z是不依赖x或y,可以借助wc来分析zn和ze的关系。
我们设投影矩阵如下:
在观察坐标系中,we等于1,则有:
Ze=-n时,zn=-1;ze=-f时,zn=1,将其带入上式有:
有(1)有:
带入(2)有:
将A带入(1)有:
将A、B带入zn,ze关系式:
最后得到投影矩阵:
当视见体是对称的,有r=-l,t=-b,则:
由(3)式看到,ze和zn成反比,ze去[-f,-n],有图像看出,在近投影面zn有较高精度,在远投影面精度低,当区间[-f,-n]增大时,靠近远投影面的点的zn由于过分靠近而超出计算机最大精度(z-fighting),即ze在较远处的细小差别不能在zn上得到表达,而具有相同的zn值。
所以,区间[-f,-n]应尽可能短,以避免精度问题。
正投影
不存在透视计算,要做的只是将一个长方体映射成正方体。
齐次项w不再需要,第四行写为(0,0,0,1):
当是对称情况时,r=-l,t=-b:。