码迷,mamicode.com
首页 > 其他好文 > 详细

D3D Project 矩阵推导

时间:2015-08-07 22:04:55      阅读:381      评论:0      收藏:0      [点我收藏+]

标签:

D3D Project 矩阵推导

D3D中, 从模型\场景到显示在屏幕上, 一般会涉及到 3 个坐标系, 4 个矩阵. 其中: 模型坐标系(Local Matrix), 世界坐标系(World Matrix), 相机坐标系(View Matrix), 这几个坐标系与矩阵相对应. 最后要把三维的模型显示在二维的屏幕上, 还需要一次投影变换, 对应的就是 Project Matrix.

Project Matrix 与其他三个不同, 其他三个可以认为是”位置”. Local Matrix => 模型的一部分相对整个模型的位置; World Matrix => 模型相对于场景的位置; View Matrix => 相机在场景中的位置. Project Matrix 表示的是投影变换.

Project 投影是一种什么样的变换?

在线性代数和泛函分析中,投影是从向量空间映射到自身的一种线性变换,是日常生活中“平行投影”概念的形式化和一般化。同现实中阳光将事物投影到地面上一样,投影变换将整个向量空间映射到它的其中一个子空间,并且在这个子空间中是恒等变换。[维基百科]

所以, 投影可能造成维度的降低. 工程图学中, 画剖面图用的是平行投影. 素描会用到透视投影. 照相机也是用的透视投影. 三维的模型经过投影后, 会变成二维的画面.

D3D中常用的投影是透视投影(在某些情况下, 也会用到平行投影, 比如拍摄场景地图的时候). 下图是很常见的透视示意图. 可以想象为: 一个人在屋里, 透过窗户看到的景象. 人的眼睛位于原点处, 近平面(near plane)就是窗户的玻璃, 远平面(far plane)则是远处的山, 视线到这里就是尽头了. 近平面, 远平面之间的锥体就是视锥.

技术分享

视锥示意图

投影会造成维度变化. 从三维到二维, 会有一个维度丢失. 相机是一个投影装置, 我们的眼睛也是. 在我们看世界时, 如果一个东西被遮挡了, 我们就看不见了. 也就是说, 在单次的投影中, ”深度”这个维度其实丢失了.

技术分享

投影维度变化(直线A, B上的点在投影后是一个点)

上图表现在更直观些: 直线AB上的点, 在投影后都是用一个点表示.

Project 矩阵如何推导?

在D3D中, 点的位置一般用齐次坐标表示, 就是一个四维向量, 第四个分量一般为 1.

齐次坐标的缘由这里不赘述.

技术分享

这是在相机坐标系中, 从X轴方向看过去的情况. 向上的坐标轴为 Y 轴. 相机在原点位置.

透视投影, 会把 OAB 上的点都投成一个点.

现在, 我们把坐标投影到近平面上, 并且, 投影后近平面上的点, Z值为 0.

A点坐标 技术分享

B点坐标技术分享

Project Matrix 记为 P.

则:

技术分享

就是A点B点, 经过投影变换后, 坐标的 x, y 分量相等.

根据三角形相似, 有:

技术分享

只有Z 值与相机位置相关, 就用它做参照.

A = 技术分享

B = 技术分享

技术分享

AP = 技术分享

BP = 技术分享

最后分量归一化后:

技术分享

所以有:

技术分享

技术分享

由:

技术分享

技术分享

技术分享

技术分享

技术分享

技术分享

所以:

技术分享

因为是投影到近平面上, 所以近平面上的点坐标不变:

技术分享

所以:

技术分享

技术分享

技术分享

技术分享

所以:

技术分享

综上:

技术分享

这就是初步的投影矩阵.

D3D的文档里, 是用两步获得的这个矩阵, 原理是一样的.

至于为什么要调整 P[2][3]这个元素, 是因为要实现X,Y的同时缩放, 而且缩放与Z值相关, 只能调整齐次坐标的最后一个分量, 这样归一化后, 才会同时缩放 X, Y.

容易知道要X, Y 都除以Z, 但这样写是不行的:

技术分享

因为 Z 是一个变量, 应该来自要变换的向量. 这样就容易找到应该修改P 的第4列, 第3个元素, 它刚好会与向量的Z相乘, 又会影响结果的第 4 个分量.

为什么说是初步的呢?

当拒这个矩阵没有考虑视口(ViewPort).

更重要的原因是Z值的原因.

仅仅看 X, Y, 这样做是没问题的. 理论上, 投影的结果Z值都是一样的就OK.

但在三维空间中, 还存在遮挡的关系. 投影中前面的物体会遮挡住后面的物体. 简单的做法就是用物体的Z值 (深度) 区分.

如果用这个矩阵投影, 近平面的Z值是0, 无穷远处的Z值才是1. 从近平面到无穷远, 中间有很长距离的Z值会相差极小(小于浮点误差), 造成难以分辨哪些在前哪些在后. 前面遮挡后面就难以实现了.

在保证X,Y正确的情况下, D3D文档中给出了另一个投影矩阵.这个矩阵对Z值的区分度要好很多.

D3D Project 矩阵推导

标签:

原文地址:http://www.cnblogs.com/davelink/p/4711711.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!