3D数学-裁剪空间与透视投影矩阵的推导
3D数学-裁剪空间与透视投影矩阵的推导
透视投影矩阵的变换本质,是将视锥体变换到裁剪空间中
视锥体的具有六个面,近裁剪面,远裁剪面,左裁剪面,右裁剪面,上裁剪面,下裁剪面
所有超出视锥体的都会被舍弃,也就是被裁剪,我们之后的操作都是对视锥体内部进行计算
接下来我们来分析并解析,如何推导透视投影矩阵
注意:这里我们对于坐标的矢量使用的是行矢量,如果你使用的是列矢量,那么透视投影矩阵要进行转置
在之前的章节中,我们已经知道了:
将点p
投影到z=d
的平面上,通过相似三角形的比例关系,可以获得p'
p[x,y,z]
--> p'[dx/z,dy/z,d]
我们使用齐次坐标理论去改变它
p'=[dx/z,dy/z,d]=[dx/z,dy/z,dz/z]=[x,y,z]/(z/d)
我们将这个分母放入w
,那么四维齐次坐标将会是:[x,y,z,z/d]
,之后我们要将齐次坐标转化为三维坐标只需要将各个分量除以w
即可。
实际上,d
值表示焦距,即从投影平面到投影中心的距离,它的值并不重要,我们将其选择为最方便的值:1
投影在平面上的z值我们并不关心,之所以选择使用d=1
,主要是原z
值对于后续的计算仍然有作用,因此我们要保存它
这样以来,齐次坐标就变为了:[x,y,z,z]
此时,透视投影矩阵是这样的:
[1 0 0 0]
[0 1 0 0]
[0 0 1 1]
[0 0 0 0]
现在,我们考虑裁剪空间的坐标[-1,1]
,之前我们的计算仅仅考虑到了将点投影在平面上,但是这仍然不够。
因为,实际上,我们希望将视锥体内的坐标,转化为裁剪空间下的坐标,而裁剪空间是什么坐标?
裁剪空间下的坐标,x[-1,1] y[-1,1] z[-1,1]
,因此,上述的透视投影矩阵还不够全面,不仅如此,我们还需要考虑到x,y的缩放,以及将z
的值映射到[-1,1]
的范围内。
现在,我们用一些字母参数重新描述透视投影矩阵
[zoomx 0 0 0]
[0 zoomy 0 0]
[0 0 a 1]
[0 0 b 0]
现在我们来解释一下这些字母参数
zoomx
与zoomy
分别表示x
轴与y
轴的缩放(根据相机的缩放控制),这很容易理解
a
和b
,用于将z值映射到[-1,1]
我们首先计算通过该矩阵变换后的齐次坐标
[x,y,z,1][zoomx 0 0 0] = [zoomx*x,zoomy*y,az+b,z][0 zoomy 0 0][0 0 a 1][0 0 b 0]
变换后的齐次坐标为:[zoomx*x,zoomy*y,az+b,z]
将齐次坐标转化为普通坐标:[zoom*x/z,zoomy*y/z,(az+b)/z,1]
之前我们说明了,我们要将视锥体中的点转换到裁剪空间中。现在先处理z
值,将其映射到[-1,1]
我们定义从原点到近裁剪平面的距离为n
,从原点到远裁剪平面的距离为f
。
我们可以列出方程:
(az+b)/z = -1 , z = n
(az+b)/z = 1 , z = f
我们可以求出a
和b
的值
a = (n+f)/(f-n);
b = -2nf/(f-n);
现在我们已经求出第一版的透视投影矩阵了,即
[zoomx 0 0 0]
[0 zoomy 0 0]
[0 0 (n+f)/(f-n) 1]
[0 0 -2nf/(f-n) 0]
我们还没有将x
和y
映射到[-1,1]
的范围内
这里我们首先介绍一种数学方法
简单的线性插值
这是在图形学中普遍使用的基本技巧,我们在很多地方都会用到,比如2D位图的放大、缩小,Tweening变换,以及我们即将看到的透视投影变换等等。基本思想是:给一个x
属于[a, b]
,找到y
属于[c, d]
,使得x
与a
的距离比上ab
长度所得到的比例,等于y
与c
的距离比上cd
长度所得到的比例,用数学表达式描述很容易理解:
(x - a)/(b - a)=(y - c)/(d - c)
这样,从a到b的每一个点都与c到d上的唯一一个点对应。有一个x,就可以求得一个y。
此外,如果x不在[a, b]内,比如x < a或者x > b,则得到的y也是符合y < c或者y > d,比例仍然不变,插值同样适用。
现在我们使用这种方法将x
和y
映射到[-1,1]
范围内
我们再次强调我们获得的齐次坐标:[zoomx*x,zoomy*y,az+b,z]
,我们暂时忽略zoomx
和zoomy
(x/z - left)/(right - left) = (x' - (-1))/(1- (-1))
(y/z - bottom)/(top - bottom) = (y' - (-1))/(1- (-1))
我们计算出x'
和y'
x' = (2x / z)/(right - left) - (right + left)/(right - left)
y' = (2y / z)/(top - bottom) - (top + bottom)/(top - bottom)
我们将重新z
乘回去,获得齐次坐标下的x
和y
x' = (2x)/(right - left) - (right + left)/(right - left)*z
y' = (2y)/(top - bottom) - (top + bottom)/(top - bottom)*z
我们将其写到矩阵里,最终我们就可以获得完整的透视投影矩阵了
[(2)/(right - left) 0 (right + left)/(right - left) 0]
[0 (2)/(top - bottom) (top + bottom)/(top - bottom) 0]
[0 0 (n+f)/(f-n) 1]
[0 0 -2nf/(f-n) 0]
我们将上面这个矩阵称为M(这里其实还不完整,记得把zoomx
,zoomy
乘回去)
最终从视锥体变换到裁剪空间的表示式
[x,y,z,1] M = [x',y',az+b,z]
转化为普通三维坐标
[x'/z,y'/z,(az+b)/z,1]
我们在将相机缩放参数加回去,就是完整的裁剪空间坐标
[zoomx*x'/z,zoomy*y'/z,(az+b)/z,1]
当然,在根据不同约定下,a
和b
的值会有所不同,例如在DirectX风格的约定下,z[0,1]
那么我们之前的计算就会有所不同,矩阵当然也有所不同。在OpenGL下,由于使用的是列矢量进行计算,因此相对于我们这里的矩阵,要进行转置
我们之前讨论的都是透视投影矩阵,对于正交投影矩阵其实很简单,就是最后一列的变化
[0,0,1,0]
–>[0,0,0,1]
,正交投影矩阵不需要根据距离的大小进行缩放。
屏幕空间
我们已经将视锥体裁剪到裁剪空间下了,那么最后我们需要将裁剪空间投影到屏幕空间,屏幕空间当然是2维空间。
首先就是进行标准化齐次除法,也就是除以w
(OpenGL中将此结果称为归一化设备坐标),其实就是将之前的齐次坐标转化为普通三维坐标,我们之前已经做过了。
然后就是缩放x
和y
坐标,以映射到输出窗口上。
输出窗口如下:
裁剪空间的坐标中x
和y
是[-1,1],但是输出窗口的坐标系和这不太一样,他的原点通常位于左上角。
而我们的窗口原点则为[winPosx,winPosy]
,[0,0]
则是屏幕的原点,因为我们的窗口并不一定覆盖整个屏幕设备
我们的画面是在窗口中的,也就是图中较小的框框内。
裁剪空间的齐次坐标:[x,y,z,w]
首先进行齐次除法
x' = x/w
y' = y/w
然后我们要将这个坐标映射到我们屏幕中窗口的坐标中
screenx = (x'*winResx)/2+winCenterx
screeny = -(y'*winResy)/2+winCentery
完整的写法
screenx = (x*winResx)/2w+winCenterx
screeny = -(y*winResy)/2w+winCentery
那么我们会有疑问,z
有什么用?它被存储在深度缓冲,并用于深度测试。这一点有一定基础的读者应该容易理解。
另外w值也还有作用,在光栅化阶段,还需要用到它。
3D数学-裁剪空间与透视投影矩阵的推导相关推荐
- 3D数学之透视投影矩阵的推导
视锥体 如图,近截面与远截面之间构成的这个四棱台就是视锥体,而透视投影矩阵的任务就是把位于视锥体内的物体的顶点X,Y,Z坐标映射到[-1,1]范围.这就相当于把这个四棱台扭曲变形成一个立方体.这个立方 ...
- Unity中的3D数学—02向量与矩阵
1.向量 1.1 向量的运算 运算 公式 矢量和标量的乘/除法 k v = ( k v x , k v y , k v z ) k\mathbf{v}=(kv_x,kv_y,kv_z) kv=(kvx ...
- webgl学习之路(三)——透视投影矩阵的推导过程
关于透视投影矩阵的讲解,网上有不少教程,但是有一点大家基本上都没有讲清楚:就是z轴坐标(这里的Z轴相当于景深)的推导过程,基本上是一笔带过. 下面先从头开始讲推导过程,再慢慢说Z轴的推导过程. 透视投 ...
- 【转载+补充】“最简单的” 相机透视投影矩阵推导与解析
原文链接 作者:大其心宏其量扩其识 链接:https://www.jianshu.com/p/09fef48e7b0f 来源:简书 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. ...
- 透视矩阵的推导(最直观、最深入、最还原,看完请点赞。)
由参数l,r,b,t,n,f定义的透视投影矩阵的推导困惑了我差不多一个多礼拜,这几天几乎是天天都在思考这个问题,昨天晚上3点多钟我突然醒了,然后我又开始想这个问题,结果终于让我给想通了,于是我赶紧起床 ...
- Cesium 透视投影矩阵推导
一.透视投影 透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume)中,待裁剪完毕后进行透视除法的行为.在算 ...
- 图形学中透视投影矩阵推导
透视投影矩阵是图形学一道重要的坎,他是将世界空间转到屏幕空间,再将屏幕放进裁剪空间ndc映射 我们从侧视图看 我们的已知条件 1.aspect:屏幕宽高比 2.n:近截面z轴坐标 3.f :远截面z轴 ...
- 【OpenGL】透视投影矩阵推导
项目场景: 系统:ubuntu glad + glfw + opengl3.3 复习games101MVP变换,在使用OpenGL检验推导透视投影矩阵时,发现得出结果的Z坐标与把不符合目标预期.可以看 ...
- 3D数学读书笔记——矩阵基础番外篇之线性变换
本系列文章由birdlove1987编写.转载请注明出处. 文章链接:http://blog.csdn.net/zhurui_idea/article/details/25102425 前面有一篇文章 ...
最新文章
- leetcode-102 二叉树的层次遍历
- 在GitHub上管理项目
- 关于request取中文字符串变?的解决办法
- 构建高可用LVS + keepalived+httpd和双主模型的keepalived方案
- oracle rac应急_ORACLE紧急情况检查应急预案
- C++经典面试题(最全,面中率最高)
- flask项目开发中,遇到http 413错误
- linux怎么看是否安装kde桌面,ubuntu 7上安装kde桌面
- JSTL标签库中fmt标签,日期,数字的格式化
- 理论与实践:如何从Hadoop迁移到MaxCompute
- MATLAB学习——矩阵
- mysql创建临时表 分页_Mysql 如何创建一张临时表
- 全新玖五社区系统整站源码
- Arcgis Server 10.4.1 搭建集群环境
- python自动化办公 51cto_聊聊 Python 办公自动化之一 Excel
- 理想的正方形 HAOI2007(二维RMQ)
- 5款Mac极速下载工具推荐和下载
- matlab实现图像直方图
- 实验五:大数据可视化工具-NodeXL
- Roundcube开启用户自助更改密码功能