[3D基础]投影矩阵的推导(1)

转眼我做游戏行业已经八个月了,游戏行业入门门槛低,所以还算学习得比较轻松,总结了当初自己迷惑的几个知识点,本来想写出来给初学者解惑,无赖我是一个懒散的人,一直拖到现在,终于决心白纸黑字的搬到Blog上来,希望大家喜欢。

投影变换:我觉得这个是3D到2D变换中最让初学者头晕的问题,但又是最重要的。


请看上面这张我用爪子抓出来的图。这个坐标系是DX的左手坐标系,Y向上,X向右,Z向内,几何坐标已经经过了相机坐标系的变换,相机位置为(0,0,0),假设远裁减面距离为f,近裁减面距离为n,近裁减面左边为l,右边为r,上为t,下为b。要投影的2个顶点A和B坐标分别为A(Xa,Ya,Za),B (Xb,Yb,Zb),现在我们要求他们的投影点坐标A0和B0,这里我以B点为例子,讲解投影最简单的几何知识。

首先我们来计算B0点的X坐标,(虚线都是辅助线),我们看三角形B C O和三角形B0 K O,利用初中几何知识可得他们是相似的,由相似三角形定理可知,B0 K = B C * ( n / C O );而B C等于Xb, C O等于Zb;所以Xb0 = Xb * n / Zb; 同理Yb0 = Yb * n / Zb;我们知道DX把3D坐标映射到了一个X(-1,1) Y(-1,1) Z(0,1)的一个立方体内。那现在我们就需要对投影后的坐标进行一维映射了,(其实投影就是映射,数学形式为函数,将一个值域一一映射到另外一个值域),现在在X轴上,我们要把l - r这个值域中的值一一映射到-1 - 1之间,what should we do?很显然我们有一个等式 ( x - l ) / ( r - l ) = ( x0 - ( -1) ) / ( 1 - ( -1 )); x是l - r之间的一个值,x0是-1 - 1之间的一个值,我们得到 x0 = (2x - ( r + l )) / ( r - l );这里的x换成Xb0得:x0 = (2n * Xb) / (Zb*( r - l )) - ( r + l )/( r - l );同理:y0 = (2n * Yb) / (Zb*( t - b )) - ( t + b )/( t - b ); Zb映射最简单,将n - f之间的值映射到0 - 1之间, z0 = Zb / ( f - n ) - n / ( f- n );现在我们把这些四则运算用矩阵形式来表示:

[x, y, z, 1] * [ 2n/(r-l)  , 0       , 0       , 0 ]
          [ 0,      , 2n/(t-b)   , 0       , 0 ]
          [ -(r+l)/(r-l), -(t+b)/(t-b), z/(f-n)  , 1 ]
         [ 0,      , 0       , -z*n/(f-n), 0 ]

得到的结构应该是[x0, y0, z0, w]->[x0/w, y0/w, z0/w, 1]

但为了3D引擎后期光栅化时方便的对中间象素的Z值进行线性插值,最好直接保存顶点的1/Z值,然后将1/Z嵌位到0~1之间。

[x, y, z, 1] * [ 2n/(r-l)  , 0        , 0     , 0 ]
         [0,      , 2n/(t-b)  , 0     , 0 ]
          [ -(r+l)/(r-l), -(t+b)/(t-b), 0     , 1 ]
          [ 0,      , 0        , 1     , 0 ]  //直接保存1/Z

将1/Z嵌位到0~1之间(线形映射) z0 = (1/Bz - 1/n)/(1/f - 1/n); [1/n->0, 1/f->1]

转换先形式使矩阵理解更加明了:z0 = f/(f-n) - f*n/((f-n)*z)

[x, y, z, 1] * [ 2n/(r-l)  , 0       , 0      , 0 ]
          [ 0,      , 2n/(t-b)  , 0       , 0 ]
          [ -(r+l)/(r-l), -(t+b)/(t-b), f/(f-n)   , 1 ]
          [ 0,      , 0        , -f*n/(f-n) , 0 ]

我看到实时计算机图形学上写出的答案与我推导出来的有点不一样,红色部分符号相反,颇为不解,不知道我错在哪里,希望明白的朋友指点迷津。

时间: 2024-12-16 06:27:08

[3D基础]投影矩阵的推导(1)的相关文章

D3D的投影矩阵推导[转贴]

原帖地址:http://blog.csdn.net/popy007/article/details/4091967       上一篇文章中我们讨论了透视投影变换的原理,分析了OpenGL所使用的透视投影矩阵的生成方法.正如我们所说,不同的图形API因为左右手坐标系.行向量列向量矩阵以及变换范围等等的不同导致了矩阵的差异,可以有几十个不同的透视投影矩阵,但它们的原理大同小异.这次我们准备讨论一下Direct3D(以下简称D3D)的透视投影矩阵,主要出于以下几个目的: (1) 我们在写图形引擎的时

[3D基础]切空间推导原理(3)

本篇为3D基础的第3部分,主要讲述顶点切向量的计算原理,相信很多人都对Shader里的Tangent分量没有深入了解,希望我的这篇文章能对各位理解切空间有所帮助.我们以凹凸映射为例子来解释今天的原理. 实际上凹凸贴图中存储的发现扰动值实际上是以图中X Y为基的(对凹凸映射不太熟悉的请先参考其他相关文章).所以需要一个转换将纹理坐标系转换到世界坐标系中,这个转换其实是一个基变换过程(参见3D基础2),说白了就是要找到纹理在世界空间中是如何摆的,纹理在方向的变化率如何.而要得到这点,需要计算得到U

[3D基础]3D游戏中的各种旋转与基变换(2)

终于开始着手写[3D基础]系列的第二篇文章了,这篇文章所将的内容相信对于很多人而言都是相当重要的,因为涉及到相机坐标系变换,BILLBOARD实现原理,凹凸映射切空间变换等课题.按以前的习惯,重要内容用红色字体标出,对于最基本的线性代数理论不作证明,使用DX左手坐标系. 第一个问题:UVN相机坐标变换形式与原理. 我们知道3D世界空间到相机空间坐标的转换是通过UVN矩阵来实现,运算格式如下: | Ux, Vx, Nx | | x, y, z | * | Uy, Vy, Ny | | Uz, Vz

dlt-基础矩阵(F矩阵)和投影矩阵把我弄混了

问题描述 基础矩阵(F矩阵)和投影矩阵把我弄混了 我一直看的是根据两组二维坐标求基础矩阵(也就是F矩阵),可是今天看了一个源码,是根据一组二维坐标和一组三维坐标求投影矩阵(好像叫DLT标定法).那到底是应该先求投影矩阵再根据投影矩阵求内参,外参,还是先求基础矩阵,再根据基础矩阵求投影矩阵?

opengl 教程(12) 投影矩阵

原帖地址:http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html        现在我们开始学习如何把三维物体投影到二维平面上,同时保持它的深度.通常的投影包括平行投影和透视投影:平行投影比较简单,就是把顶点垂直的投向投影平面,常用在cad或者机械制图中.另外一种投影是透视投影,这种投影能较好的使二维投影显示立体感,因为人眼观看物体符合透视原理,透视原理也是学美术的人的必修课程.最常见的透视原理表现形式就是三维世界的平行线在透视几何中

极线校正-计算机视觉中给定两幅图像以及投影矩阵情况下,如何计算极线影像?

问题描述 计算机视觉中给定两幅图像以及投影矩阵情况下,如何计算极线影像? 已知条件只有两幅影像和对应投影矩阵,我通过查阅资料发现采用stereoRectify函数可以进行极线校正,最后得到极线影像(就是水平对齐,y视差为0),那么在输入函数参数中,我有以下几个问题: 1.cameraMatrix1,R,T是否可以直接用投影矩阵P分解得到?就是对应的K R T么? 2.distCoeffs参数怎么获取得到呢?或者是默认不存在畸变? 3.本人采用的方法是否正确,就是采用stereoRectify此方

《Unity 3D 游戏开发技术详解与典型案例》——1.1节Unity 3D基础知识概览

1.1 Unity 3D基础知识概览 Unity 3D 游戏开发技术详解与典型案例 本节主要向读者介绍Unity 3D的相关知识,主要内容包括Unity 3D的简介.Unity 3D的发展和Unity 3D的特点等.通过本节的学习,读者将对Unity 3D有一个基本的认识. 1.1.1 初识Unity 3D Unity 3D是由Unity Technologies开发的一个轻松创建三维视频游戏.建筑可视化.实时三维动画等互动内容的.多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎. Un

【线性代数】最小二乘与投影矩阵

        前一篇文章<正交投影>中我们讲述了正交投影,现在我们来从正交投影的角度来看看我们熟悉的最小二乘法.我记得最早知道最小二乘法是在大一上高数课的时候,我们首先回顾一下什么是最小二乘法. 1.最小二乘法         最近机器学习比较火,机器学习中的许多算法都是对信息进行分类,比如说支持向量机就是根据已知信息来分类,神经网络可以找到输入输出的关系(当然,不能给出具体的数学表达式),这两种算法都能找到输入与输出的关系,分类和回归总是相辅相成的.以后有时间也准备写写关于机器学习方面的算

视图矩阵的推导

        把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵.      下面我们先看下OpenGL中视图矩阵的推导过程:      假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视点则处于局部坐标系的原点位置.      就如OpenGL中的函数gluLookAt(eyex, eyey, eyez, lookatx, lookaty, lookatz, upx, upy, upz)一样,给定视点.观察点.以及up向量之后,我们就可以求得视