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

向量 C
x
(位移)向量
虽然多数时候向量纯粹表达方向,但事实上它还带有
长度的信息,向量{x,y,x}在3D空间的长度 是 。故,可以把向量理解为在一个方向 上长度为 的位移。 例如两点之间的距离向量,就是一个典型的位移向量。
我们通常结合上下文,来判断向量是纯粹方向的还是
位移的向量。
向量的基本运算:加法
坐标系的转换和矩阵
后续的内容主要记录World坐标系转换之后的Camera
坐标系,Projection坐标系的转换。
接下来记录的转换矩阵推导,是用DirectX来举例。事
实上,这些推导过程在OpenGL上也是一样的,如果 有差别,也是一些数值上的细微差别,例如DirectX的 远近裁剪面定为[0~1],而OpenGL的定为[-1~1]。
太少了,列举不出来呀。
坐标系的转换
抄录自MSDN,Transform pipeline
Wiki
Transform pipeline,/en-
us/library/windows/desktop/ee418867(v=vs.85).aspx
达两者,但它们在数值层面是一致的。 因方向向量的核心是方向,故两个方向向量的x,y,z数 值可能不同,但方向却是一样的,我们认为这两个方 向向量等价。
点和(方向)向量
方向向量C和B
等价,因它们表达 的方向是相同的。 数值上点A和向量 B相等,但物理意义 不同
y
z
点A{5,2,6} 向量B {5,2,6}
注意到上式左边是叉乘结果向量的模的平方,所以对
等式两边开平方,即得:
上式便是关于叉乘的模的等式。至此,我们知道叉乘
会得到一个垂直于原来两个向量(以及它们所在平面) 的向量,且这个向量的长度满足上述等式。但仍有一 个问题:这个垂直向量朝向那个方向呢?
摄像机矩阵和投影矩阵推导

坐标系旳转换和矩阵
后续旳内容主要统计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坐标系。
透视投影矩阵推导

透视投影矩阵推导 计算机图形学中,建模⾃⼩孔成像原理的透视摄像机是常⽤的摄像机模型。
然⽽,由于光栅化渲染中的⼏何变换多基于四阶⽅阵与齐次坐标表⽰的向量的乘法,⽽四阶⽅阵只能表⽰仿射变换,⽆法实现透视摄像机“近⼤远⼩”的特性(仿射变换维持平⾏线相互平⾏,⽽“近⼤远⼩”不具有该性质),因此透视摄像机模型的实现要多费⼀番功夫。
1. 基本原理 ⼩孔成像是⼤多数⼈所熟知的最简单的成像原理之⼀,⽽常⽤的透视摄像机就是把⼩孔和屏幕(成像平⾯)的顺序交换,维持相似关系不变,因⽽这⼀模型达到了拟真的效果⽽被⼴泛应⽤。
⼩孔成像与简单的透视摄像机模型 透视摄像机模型⽤在光栅化渲染管线的结果,就是透视投影过程。
考虑简图—— 图中从e点(原点)发出的⼀条射线上所有在view plane之后的点都被投影到view plane与该射线的交点。
由相似关系显然有这就得到了所需的映射关系: 显然并⾮仿射变换,也就不能直接借助四阶⽅阵乘法来实现。
这时齐次坐标表⽰的另⼀个作⽤就表现出来了,设齐次坐标表⽰点,定义全体的齐次坐标上的等价关系:当且仅当,则有,该式的右边正是常⽤的齐次坐标中点的表⽰⽅法()。
这样⼀来,这⼀等价关系为我们提供了“除法”的能⼒,也扩充了仿射变换的能⼒。
注意到,仿射变换可以将、、中的任意⼀个分量设置为,⽽该⽅法允许这样的变换形式——注意到透视投影需要的变换是(假设viewing transform后摄像机⾯向+z⽅向)⽽要将映射为是很容易的,只需要矩阵乘法——然后使化为即可,这⼀过程称为齐次化。
这就是齐次坐标投影的基本原理。
2. 完整的投影矩阵推导 现实中使⽤的投影矩阵因为考虑了摄像机视截体,形式更加复杂。
考虑下图中的透视投影变换—— 显然该变换把近平⾯(near plane)区域投影到xOy平⾯上的单位正⽅形。
在这⾥可以把该变换过程拆分成三个⼦过程:完成“透视”投影、把near plane上的视窗变换为单位正⽅形、把near plane的z坐标变换为0。
简单的ViewingFrustumCulling投影矩阵推导视锥体,清晰

简单的ViewingFrustumCulling投影矩阵推导视锥体,清晰Viewing Frustum Culling是图形绘制流⽔线中,将不可见物体(即不在视锥体内的物体)提前剔除的操作。
在实践中,精确判断物体的可见性开销较⼤,因⽽通常⽤物体包围球或包围盒与视锥体(平截头体,View frustum)做相交测试,以此粗略判断物体是否可见。
进⼀步地,我们可以采⽤如下⽅式来⼤致判断⼀个球体与视锥体是否相交:球与视锥体相交的必要(⾮充分)条件是:其中⼼P与视锥体的6个⾯的符号距离(Signed distance)d均⼩于球的半径R。
注意对于⼀个平⾯aX + bY+ cZ + d = 0 ([a, b, c]为平⾯法线⽅向N,d为平⾯与原点的符号距离), ⼀个点P(x, y, z)与该平⾯的符号距离为ax + by + cz + d。
因此要粗略判断物体与视锥体是否相交,只需要将其包围球与视锥体的6个⾯分别计算符号距离即可,如果其与任⼀⾯的符号距离⼤于R,则可安全剔除。
那么如何算得视锥体每个⾯的⾯⽅程呢?⼀个⽐较通⽤的⽅法是求出视锥体的8个顶点,然后分别利⽤叉积和点积求出6个⾯的法线和原点距。
但如果我们已经知道投影矩阵,也可以⽤如下更简单的⽅法算得⾯⽅程:(以Direct3D为例,OpenGL与之相似,但需要注意的是其规范化设备坐标系的Z取值范围为[-1,1]⽽⾮[0,1])对于⼀个场景,设物体空间中有⼀球体,中⼼坐标为P,半径为R,由某⼀视锥体定义的物体空间到规范化设备空间的变换矩阵为M= World *View *Projection。
现需要求该视锥体各个⾯在物体空间中的⾯⽅程。
回顾规范化设备坐标系的定义,我们可以很容易得知,M的效果可以看做是将视锥体的6个⾯分别变换到X=1, X=-1, Y=1, Y=-1, Z=0, Z=1这6个⾯上。
例如,视锥体的近剪裁⾯经过M,会变换到Z=0平⾯上,远剪裁⾯变换到Z=1平⾯上,其他4个⾯也是类似变换。
投影矩阵的推导

投影矩阵的推导(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)是坐标系下表达一个向量和点的不同表达方式。
投影矩阵的计算过程

投影矩阵的计算过程投影矩阵是一种线性变换矩阵,用于将三维空间中的点投影到二维平面上。
投影矩阵在计算机图形学和计算机视觉中经常被使用,例如生成透视投影效果或者在三维场景中进行物体检测。
在计算过程中,首先需要确定投影平面。
常见的投影平面有平行投影平面和透视投影平面两种。
平行投影平面与三维空间平行,通常用于绘制平行投影效果。
透视投影平面通过一个视点与投影平面的插值方式计算投影效果,模拟真实世界中的透视效果。
下面分别介绍平行投影矩阵和透视投影矩阵的计算过程。
1.平行投影矩阵计算过程:平行投影矩阵使用一个正交投影矩阵生成,平行投影矩阵的计算过程如下:1.1确定投影平面的尺寸:根据需要确定投影平面的长度和宽度。
1.2计算投影矩阵的元素:在平行投影矩阵中,x、y、z三个坐标轴的长度比例通常是相同的。
首先,需要确定x和y方向上的比例系数,通常是投影平面的长度和宽度的倒数。
然后,z方向上的比例系数由投影平面的远近关系决定,如果投影平面的远近关系与三维场景的z方向相同,则比例系数为正,否则为负。
最后,将这三个比例系数填入平行投影矩阵的对角线位置上,其他位置上的元素为0。
1.3平移投影平面:平行投影矩阵只能将点投影到位于原点的平面上,如果需要将投影平面平移至指定的位置,可以通过在平行投影矩阵中添加平移矩阵来实现。
平移矩阵的计算过程可以参考矩阵乘法操作。
2.透视投影矩阵计算过程:透视投影矩阵将三维空间中的点投影到一个透视投影平面上,通常通过一个视点与投影平面的插值方式计算投影效果。
2.1确定投影平面的尺寸:根据需要确定投影平面的长度和宽度。
2.2确定视点的位置:根据需要确定视点在三维空间中的位置,常见的视点位置是位于投影平面后方的一些点。
2.3计算透视投影矩阵的元素:透视投影矩阵的元素计算与平行投影矩阵类似,首先需要确定x和y方向上的比例系数,通常是投影平面的长度和宽度的倒数。
然后,z方向上的比例系数由视点与投影平面的插值方式计算,可以根据视点的位置和投影平面的位置来计算出比例系数。
矩阵变换:沿任意方向缩放、镜像、正交投影及切变及其推导

[ k x 0] ,
q′ k= = k y [1 = 0] xq 0 k y ,
得到缩放矩阵:
kx S ( kx , k y , kz ) = 0 0 0 ky 0 0 0 kz
2
kx [ x y z] 0 0
同样的原理运用在 3D 中
p = [1 0 0] ,
2 1 + ( k − 1) nx = p′ ( k − 1) nx n y , ( k − 1) nx nz Τ
q = [ 0 1 0] ,
( k − 1) nx n y 2 q′ = 1 + ( k − 1) n y , ( k − 1) n y nz ( k − 1) nx nz = r′ ( k − 1) n y nz . 2 1 + ( k − 1) nz
P 是 projection(投影)的缩写,2D 中, Px 表示向 x 轴投影, Py 同理:
1 0 = Px S = ([0 1] , 0 ) 0 0 , 0 0 Py S = = ([1 0] , 0 ) 0 1 , 3D 中, Pxy 表示向 xy 平面投影,其余同理:
4
3 正交投影
投影意味和降维操作, 将所有的点拉平到要投影的直线或平面上,从原来的 点到投影点的直线相互平行,这就是正交投影。透视投影是另一种投影。
3.1 向坐标轴或平面上投影
通过将垂直方向上缩放因子设为 0 来实现,如将 3D 点投影到 xy 平面,则抛 弃 z 分量,通过将 z 方向上的缩放因子设为 0 实现。
8
1 0 0 H xz ( s, t ) = s 1 t , 0 0 1 1 s t H yz ( s, t ) = 0 1 0 . 0 0 1
斜平行投影变换矩阵推导

斜平行投影变换矩阵推导斜平行投影是一种特殊的投影方式,它将三维物体投影到二维平面上。
在斜平行投影中,投影线与投影平面呈一定的角度,而不是完全垂直。
这种投影方式在许多领域都有应用,例如建筑设计、动画制作和虚拟现实等。
为了推导斜平行投影的变换矩阵,我们首先需要了解一些基本概念和公式。
在三维空间中,一个点的坐标可以表示为 (x, y, z)。
在二维平面上,一个点的坐标可以表示为 (x', y')。
斜平行投影的变换矩阵可以将三维坐标转换为二维坐标。
假设投影平面与x轴之间的角度为θ,那么变换矩阵可以表示为:(T = \begin{bmatrix}\cos\theta & -\sin\theta & 0 \\sin\theta & \cos\theta & 0 \0 & 0 & 1\end{bmatrix})这个矩阵将三维坐标 (x, y, z) 转换为二维坐标 (x', y'),其中 x' 和 y' 分别表示在投影平面上的横向和纵向坐标。
接下来,我们可以通过矩阵乘法来计算二维坐标。
假设三维坐标为 (x, y, z),则可以通过以下公式计算二维坐标:(T \cdot \begin{bmatrix}x \y \z \\end{bmatrix} = \begin{bmatrix}x' \y' \z' \\end{bmatrix})其中 (z' = z)。
通过矩阵乘法,我们可以得到:(x' = x \cos\theta - y \sin\theta)(y' = x \sin\theta + y \cos\theta)(z' = z)这样,我们就得到了斜平行投影的变换矩阵和对应的坐标变换公式。
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]。
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,变换稍微复杂一些。
投影矩阵的充要条件

投影矩阵的充要条件投影矩阵是线性代数中一个重要的概念,它在计算机图形学、机器学习等领域有着广泛的应用。
在理解投影矩阵的性质和特点时,我们需要了解它的充要条件。
一、什么是投影矩阵投影矩阵是一个方阵,它可以将一个向量投影到一个低维的子空间上。
具体来说,对于一个n维向量空间V中的向量x,如果存在一个n×n的矩阵P,使得Px=x,那么矩阵P就是一个投影矩阵。
二、投影矩阵的性质1. 幂等性:投影矩阵的平方等于它本身,即P²=P。
这是因为对于任意向量x,Px再次投影到子空间上仍然等于x。
2. 对称性:投影矩阵是对称矩阵,即P^T=P。
这是因为对于任意向量x和y,有x^TPy=y^TPx,即x和y的投影结果相同。
3. 特征值:投影矩阵的特征值只能是0或1。
证明如下:设P是一个投影矩阵,λ是它的特征值,v是对应于λ的特征向量。
则有Pv=λv。
由于P是幂等矩阵,有P²=P,所以Pv=P²v=P(Pv)=P(λv)=λPv=λ²v。
由于v不为零,所以λ²=λ,即λ=0或1。
三、投影矩阵的充要条件可以通过其性质来推导得出。
设P是一个n×n的矩阵,满足P²=P,P^T=P,且所有特征值都是0或1。
我们需要证明P是一个投影矩阵。
首先,由于P是对称矩阵,可以对它进行对角化,即存在一个正交矩阵Q和一个对角矩阵D,使得P=QDQ^T。
由于P是幂等矩阵,有P²=P,即(QDQ^T)²=QDQ^T。
展开得到QD²Q^T=QDQ^T,即D²=D。
由于D是对角矩阵,所以D的对角元素只能是0或1。
因此,P的特征值只能是0或1。
其次,我们需要证明P满足Px=x。
对于任意向量x,有Px=QDQ^Tx=QD(Q^Tx)。
由于D是对角矩阵,所以Q^Tx是一个向量,记作y。
则有Px=QDy=Q(Dy)=Q(Dy)=Qy=x。
因此,P满足Px=x。
透视投影矩阵的推导

透视投影矩阵的推导视锥体如图,近截⾯与远截⾯之间构成的这个四棱台就是视锥体,⽽透视投影矩阵的任务就是把位于视锥体内的物体的顶点X,Y,Z坐标映射到[-1,1]范围。
这就相当于把这个四棱台扭曲变形成⼀个⽴⽅体。
这个⽴⽅体叫做规则观察体 (Canonical View Volume, CVV)。
如下图:变换⽅法或规则:如下图,有⼀点P,位于视锥体内,设坐标为(x,y,z).分别对x,y坐标和z坐标的变换到[-1,1]的⽅式进⾏讨论:1.x,y坐标的变换⽅式:(1)连接视点eye与P点与近裁剪⾯交于P’点(2)设近裁剪⾯的宽度为W,⾼度为H,P’点的x坐标范围是[-W/2,W/2],y坐标范围是[-H/2,H/2],然后分别线性映射⾄[-1,1]内即可。
2.z坐标的变换⽅式z坐标的范围是N⾄F,需要映射到[-1,1],映射⽅法暂时按下,不做想法。
透视投影函数形式void Matrix4X4::initPersProjMatrix(float FOV, const float aspect, float zNear, float zFar) 透视投影矩阵构建函数的参数:Fov:纵向的视⾓⼤⼩aspect:裁剪⾯的宽⾼⽐zNear:近裁剪⾯离摄像机的距离,图中的nzFar:远裁剪⾯离摄像机的距离,图中的f通过这⼏个参数和三⾓函数的数学知识可以求得近裁剪⾯的⾼度,参考上图:求得点P在近裁剪⾯的投影点P’的坐标根据相似三⾓形对应边长度的⽐率相同,由图可得其中x’,y’的范围沿原点对称,只要将他们分别除以W/2,H/2,即可以使范围位于[-1,1]内。
前⾯已求得W,H,因此:假设我们最后需要的坐标点P’’即是推导矩阵然后为了⾃动化的得到这个结果,我们使⽤矩阵这种数学⼯具,将⼀个矩阵乘以⼀个向量,得到⼀个新的向量,使得我们所有的运算步骤和运算数据蕴藏在矩阵和乘法中。
下⾯的⼯作就是寻找到⼀个矩阵使得:我们发现求解很难找出合适的m00、m02,因为左边x和z是以加法的形式相邻,右边z确成为了x的分母。
投影矩阵

2 ⎡ ⎢ right − left ⎢ ⎢ 0 P = ST = ⎢ ⎢ 0 ⎢ ⎢ 0 ⎢ ⎣
最后的投影
令z = 0 这等价于如下的齐次坐标变换
M orth
⎡1 ⎢0 =⎢ ⎢0 ⎢ ⎣0
0 1 0 0
0 0 0 0
0⎤ 0⎥ ⎥ 0⎥ ⎥ 1⎦
从而在4D中一般的正交投影为P = MorthST
斜投影
OpenGL的投影函数不支持一般的平行投 影,例如立方体的如下图示
此时立方体好像发生了错切,然后再进行 正交投影 斜投影 = 错切+正交投影
投影规范化
把对象进行变形,使得 变形后的对象经正交投 影后得到与原对象的理 想投影一样的视图 规范化矩阵就是正交投 影矩阵串乘上对象变形 矩阵
流水线
模型-视图 变换
非奇异变换
投影变换
透视除法
4D 3D
裁剪
相对于默认立方体
投影
3D 2D
注释
在模型-视图变换和投影变换的过程中,我们 是一直在四维齐次坐标系中的
P = NSH
投影矩阵
⎡ 2near ⎢ right − left ⎢ ⎢ 0 P = NSH = ⎢ ⎢ 0 ⎢ ⎢ 0 ⎢ ⎣
0 2near top − bottom 0 0
right + left right − left top + bottom top − bottom far + near − far − near −1
线性代数笔记18投影矩阵和最小二乘

线性代数笔记18投影矩阵和最小二乘线性代数笔记18——投影矩阵和最小二乘 - 我是8位的 - 博客园一维空间的投影矩阵先来看一维空间内向量的投影:向量p是b在a上的投影,也称为b在a上的分量,可以用b乘以a方向的单位向量来计算,现在,我们打算尝试用更“贴近”线性代数的方式表达。
因为p趴在a上,所以p实际上是a的一个子空间,可以将它看作a放缩x倍,因此向量p可以用p = xa来表示,只要找出x就可以了。
因为a⊥e,所以二者的点积为0:我们希望化简这个式子从而得出x:x是一个实数,进一步得到x:a T b和a T a都是点积运算,最后将得到一个标量数字。
这里需要抑制住消去a T的冲动,向量是不能简单消去的,a和b 都是2×1矩阵,矩阵的运算不满足乘法交换律,a T无法先和1/a T计算。
现在可以写出向量p的表达式,这里的x是个标量:这就是b在a上的投影了,它表明,当b放缩时,p也放缩相同的倍数;a放缩时,p保持不变。
由于向量点积a T a是一个数字,p可以进一步写成:在一维空间中,分子是一个2×2矩阵,这说明向量b的在a上的投影p是一个矩阵作用在b上得到的,这个矩阵就叫做投影矩阵(Projection Matrix),用大写的P表达:推广到n维空间,a是n维向量,投影矩阵就是n×n的方阵。
观察投影矩阵会法发现,它是由一个列向量乘以一个行向量得到的:可以看出aa T的列向量是线性相关的,所以它的列空间和行空间的维度都是1,这说明它的秩是1,aa T是一个秩一矩阵,并且是一个对称矩阵。
由于a T a是一个标量,所以aa T决定了投影矩阵的性质:投影矩阵还有另外一个性质:它的几何意义是,对一个向量投影两次和投影一次相同,b在a上的投影是p,再投影一次仍然是p。
向量投影到子空间有什么意义呢?这要从方程Ax = b说起。
对于Ax = b来说,并不是任何时候都有解,实际上大多数这种类型的方程都无解。
关于裁剪空间与投影变换矩阵的推导

关于裁剪空间与投影变换矩阵的推导再看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实际上这个叫透视矩阵的东西实现的不仅仅是透视功能,如果要实现透视功能实际上的矩阵式这样⼦的:那多出来的这部分:是⽤来⼲什么的呢,实际上”透视矩阵“的功能不仅仅是透视,还有⼀个裁剪的功能,它可以把不在视景体内的顶点裁剪掉,则多出来的部分就是⽤来进⾏裁剪的。
正交投影矩阵计算公式

正交投影矩阵计算公式
正交投影矩阵是一种常用的投影矩阵,用于将三维空间中的点投影到二维平面上,保持直线的长度和角度不变。
正交投影矩阵的计算公式如下:
设投影平面的法向量为n,投影点到投影平面的距离为d,要计算正交投影矩阵P。
1. 首先,计算投影平面的单位法向量n',即将n向量除以其长度得到单位向量。
2. 然后,计算正交投影矩阵P = I n' n'的转置,其中I是单位矩阵。
这个公式保证了P n = 0,即投影平面的法向量经过P 变换后仍然是0向量。
3. 最后,将投影平面的距离d考虑进来,得到最终的正交投影矩阵P' = P + d n' n'的转置。
这样得到的P'就是将三维空间中的点投影到投影平面上的正交投影矩阵。
需要注意的是,上述计算公式是基于投影平面的法向量和距离已知的情况下。
如果是其他情况,可能需要进行一些变换和调整来得到正确的正交投影矩阵。
透视投影矩阵公式

透视投影矩阵公式透视投影是计算机图形学中常用的一种技术,通过透视投影矩阵,可以将三维物体映射到二维平面上,模拟出真实世界中的透视效果。
本文将介绍透视投影矩阵的原理和常用公式。
一、透视投影的原理在计算机图形学中,透视投影是通过将物体的三维坐标转换为二维坐标来实现的。
透视投影时,离观察者较近的物体会比较大,而离观察者较远的物体会比较小,从而产生了一种近大远小的效果,使画面更加逼真。
透视投影的原理可以用一个简单的模型来描述:将观察者看作位于原点的摄像机,物体位于摄像机前方的三维空间中。
当光线从物体上的某一点射入摄像机中时,两者之间形成一条射线。
我们需要找到摄像机对应的二维平面上的投影点。
二、透视投影矩阵公式透视投影矩阵是将三维坐标转换为二维坐标的关键工具。
下面是透视投影矩阵的公式:```P = M * V * P * N * v```其中,P表示投影后的二维坐标,M表示模型坐标系到世界坐标系的转换矩阵,V表示世界坐标系到相机坐标系的转换矩阵,P表示相机坐标系到裁剪坐标系的转换矩阵,N表示裁剪坐标系到标准化坐标系的转换矩阵,v表示标准化坐标系到屏幕坐标系的转换矩阵。
三、各矩阵的作用和计算方式1. 模型矩阵(M)模型矩阵将物体从局部坐标系转换到世界坐标系。
它包括平移、旋转和缩放等变换。
计算模型矩阵时,需要考虑物体的位置、旋转角度和尺寸等参数。
2. 视图矩阵(V)视图矩阵将世界坐标系转换为相机坐标系。
相机的位置和方向决定了视图矩阵的值。
通过平移相机的位置和旋转相机的方向,可以得到视图矩阵。
3. 投影矩阵(P)投影矩阵将相机坐标系转换为裁剪坐标系。
投影矩阵有两种类型:正交投影和透视投影。
正交投影用于制作二维游戏或平面设计等,而透视投影则用于模拟真实世界的透视效果。
4. 规范化矩阵(N)规范化矩阵将裁剪坐标系转换为标准化坐标系。
裁剪坐标系的坐标范围是(-1,1),而标准化坐标系的坐标范围是(0,1)。
规范化矩阵通过缩放和偏移来将裁剪坐标系的范围转换为标准化坐标系的范围。
矩阵论课件 6.1

PL ,M x y ,则有
所以 充分性. 对
P 2 PL2,M PL,M P
x C n ,因为
所以
x Px x Px Px ( I P) x
C R( P) R( I P)
n
又 z R( P) R( I P)
u,v 使
因为
z Pu ( I P)v
2 2
Pz P u P( I P)v O, 而P u Pu z C R( P) R( I P)
n
所以 z=0 ,即
所以 P 是沿 R(IP) 到 R(P) 的投影矩阵. 证毕 例 如果矩阵P 是幂等矩阵,那么 R( I P) N ( P) 证 对 xR(IP), 因为 u 使 (IP)u=x
一组基,构造分块矩阵
X ( x1 , x2 ,, xr ), Y ( y1 , y2 ,, ynr )
由 XHY=O 得
PL X O X Y 1 X O X Y X X X O O
H
H
X Y X Y H
T
(0,1,1)
T
生成的子空间,求正交投影矩阵
T
PL和向量 x (1,2,3) 沿 L 到 L 的投影.
解 因为
1 X 2 0
0 H 5 1 , X X 2 1
2 2
1 2 2 (X X ) 6 2 5
称 y 是 x 沿 M 到L 的投影. 定义6.1 将任意 xCn 变为沿M到L的投影 的变换称为沿M 到 L的投影算子,记作 PL ,M .
即
PL ,M x y
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
投影矩阵的推导(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)是坐标系下表达一个向量和点的不同表达方式。
这里可以看出,虽然都是用代数分量的形式表达向量和点,但表达一个点比一个向量需要额外的信息。
如果我写出一个代数分量表达(1, 4, 7),谁知道它是个向量还是个点!我们现在把(1)(3)写成矩阵的形式:这里(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),它就是个点。
下面是如何在普通坐标(OrdinaryCoordinate)和齐次坐标(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个最常见的仿射变换,平移变换只对于点才有意义,因为普通向量没有位置概念,只有大小和方向,这可以通过下面的式子清楚地看出:而旋转和缩放对于向量和点都有意义,你可以用类似上面齐次表示来检测。
从中可以看出,齐次坐标用于仿射变换非常方便。
此外,对于一个普通坐标的点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所说,仿射(线性)变换的进行更加方便。
由于图形硬件已经普遍地支持齐次坐标与矩阵乘法,因此更加促进了齐次坐标使用,使得它似乎成为图形学中的一个标准。
简单的线性插值线性插值我举的是丁欧南的温度计的例子:已知有一破温度计(何以谓破?刻度之间间距虽平均,但间距或大于或小于标准值,谓之破),当其插入0 0C水里时显示为50C,当其插入1000C的沸水中时显示为900C,问:当实际水温为500C时此破温度计显示的值是多少?解:因刻度均匀,所以刻度之间的比例与好温度计相同,由此:设显示的数为T,(90-T)/(T-5)=(100-50)/(50-0) 解出T=47.5 0C.结论:由一个数域(如题目中的好温度计两个端点[0,100])映射到另一个数域(如题目中的破温度计的两个端点[5,90])时,如果两个数域都是线性(就如题目中暗示的刻度平均),那么它们对应点成比例(比如50和47.5这一对端点).这道题的应用是把一组坐标映射到另一个范围,这将在介绍NDC(Normalized Device Coordinate,归一化的设备坐标)时用到.透视投影变换好,有了上面两个理论知识,我们开始分析这次的主角——透视投影变换。
这里我们选择OpenGL的透视投影变换进行分析,其他的APIs会存在一些差异,但主体思想是相似的,可以类似地推导。
经过相机矩阵的变换,顶点被变换到了相机空间。
这个时候的多边形也许会被视锥体裁剪,但在这个不规则的体中进行裁剪并非那么容易的事情,所以经过图形学前辈们的精心分析,裁剪被安排到规则观察体(CanonicalView Volume, CVV)中进行,CVV是一个正方体,x, y, z的范围都是[-1,1],多边形裁剪就是用这个规则体完成的。
所以,事实上是透视投影变换由两步组成:1)用透视变换矩阵把顶点从视锥体中变换到裁剪空间的CVV中。
2) CVV裁剪完成后进行透视除法(一会进行解释)。
我们一步一步来,我们先从一个方向考察投影关系。
上图是右手坐标系中顶点在相机空间中的情形。
设P(x,z)是经过相机变换之后的点,视锥体由eye——眼睛位置,np——近裁剪平面,fp——远裁剪平面组成。
N是眼睛到近裁剪平面的距离,F是眼睛到远裁剪平面的距离。
投影面可以选择任何平行于近裁剪平面的平面,这里我们选择近裁剪平面作为投影平面。
设P’(x’,z’)是投影之后的点,则有z’ = -N。
通过相似三角形性质,我们有关系:同理,有这样,我们便得到了P投影后的点P’从上面可以看出,投影的结果z’始终等于-N,在投影面上。
实际上,z’对于投影后的P’已经没有意义了,这个信息点已经没用了。
但对于3D图形管线来说,为了便于进行后面的片元操作,例如z缓冲消隐算法,有必要把投影之前的z保存下来,方便后面使用。
因此,我们利用这个没用的信息点存储z,处理成:这个形式最大化地使用了3个信息点,达到了最原始的投影变换的目的,但是它太直白了,有一点蛮干的意味,我感觉我们最终的结果不应该是它,你说呢?我们开始结合CVV进行思考,把它写得在数学上更优雅一致,更易于程序处理。
假入能够把上面写成这个形式:那么我们就可以非常方便的用矩阵以及齐次坐标理论来表达投影变换:其中哈,看到了齐次坐标的使用,这对于你来说已经不陌生了吧?这个新的形式不仅达到了上面原始投影变换的目的,而且使用了齐次坐标理论,使得处理更加规范化。
注意在把变成的一步我们是使用齐次坐标变普通坐标的规则完成的。
这一步在透视投影过程中称为透视除法(Perspective Division),这是透视投影变换的第2步,经过这一步,就丢弃了原始的z值(得到了CVV中对应的z值,后面解释),顶点才算完成了投影。
而在这两步之间的就是CVV裁剪过程,所以裁剪空间使用的是齐次坐标,主要原因在于透视除法会损失一些必要的信息(如原始z,第4个-z保留的)从而使裁剪变得更加难以处理,这里我们不讨论CVV裁剪的细节,只关注透视投影变换的两步。
矩阵就是我们投影矩阵的第一个版本。
你一定会问为什么要把z写成有两个原因:1)P’的3个代数分量统一地除以分母-z,易于使用齐次坐标变为普通坐标来完成,使得处理更加一致、高效。
2)后面的CVV是一个x,y,z的范围都为[-1,1]的规则体,便于进行多边形裁剪。
而我们可以适当的选择系数a和b,使得这个式子在z = -N的时候值为-1,而在z = -F的时候值为1,从而在z方向上构建CVV。
接下来我们就求出a和b:这样我们就得到了透视投影矩阵的第一个版本:使用这个版本的透视投影矩阵可以从z方向上构建CVV,但是x 和y方向仍然没有限制在[-1,1]中,我们的透视投影矩阵的下一个版本就要解决这个问题。
为了能在x和y方向把顶点从Frustum情形变成CVV情形,我们开始对x和y进行处理。
先来观察我们目前得到的最终变换结果:我们知道-Nx / z的有效范围是投影平面的左边界值(记为left)和右边界值(记为right),即[left, right],-Ny / z则为[bottom, top]。
而现在我们想把-Nx / z属于[left, right]映射到x属于[-1, 1]中,-Ny / z属于[bottom, top]映射到y属于[-1, 1]中。
你想到了什么?哈,就是我们简单的线性插值,你都已经掌握了!我们解决掉它:则我们得到了最终的投影点:下面要做的就是从这个新形式出发反推出下一个版本的透视投影矩阵。
注意到是经过透视除法的形式,而P’只变化了x和y分量的形式,az+b和-z是不变的,则我们做透视除法的逆处理——给P’每个分量乘上-z,得到而这个结果又是这么来的:则我们最终得到:上面是一般情况,我们要把它变成特殊性版本,即gluPerspective,它是一种左右对称的投影形式,因此我们从对x和y进行插值的那一步来看:那一步来看:销掉两边的1/2,得到:则我们反推出透视投影矩阵:这就是gluPerspective的投影矩阵了。