DirectX学习笔记(十三):取景变换矩阵计算及3D世界摄像机的原理分析和实现
2016-09-24 14:07
597 查看
前言:
在玩3D游戏中,我们对于整个游戏场景的视野获取就是通过摄像机来完成的。由此可见摄像机的重要性。前面的所有例子都是针对于摄像机固定来说的。这一次我们来设计一个摄像机(模拟游戏场景中的摄像机)。取景变换计算过程:
在前面我们讲过取景变换。在当摄像机的位置和朝向任意时,进行一些操作会造成效率低下很是麻烦。为了简化运算,我们将摄像机变换到世界坐标系的原点,并旋转摄像机使其光轴与世界坐标系的z轴正方向朝向一致。要特别注意的是,世界中的所有物体都会随之摄像机变换,以保证摄像机的视场恒定。如下图:
由此可见,我们要描述一个摄像机必须有四个向量:右向量(right)、上向量(up)、观察向量(look)、位置向量(position)。实际上,这些向量的定义意味着我们定义了一个局部的坐标系。
这样,我们就可以通过这四个向量来进行以下变换:
绕向量right的旋转
绕向量up的旋转
绕向量look的旋转
沿向量right方向的扫视
沿向量up的升降
沿向量look的平动
如下图所示:
那么,我们怎么才能实现这些变换呢?答案:通过矩阵运算!!
为了讲解方便,我们令向量
p = (px,py,pz)表示位置向量,position
r = (rx,ry,rz) 向量表示右向量, right
u = (ux,uy,uz) 向量表示上向量,up
d = (dx,dy,dz) 向量表示观察向量。look
我们知道,取景变换所解决的其实就是世界坐标系中的物体在以摄像机为中心的坐标系中如何来表示的问题。这就是说,需要将世界坐标系中的物体随着摄像机一起进行变换,这样摄像机的坐标系就与世界坐标系完全重合了。
第一张图中的的(a)图到(b)图,是一个平移的过程,而(b)图到(c)图则是一个旋转的过程。另外需要注意的一点是,空间中的物体也应该随着摄像机一同进行变换,这样摄像机中看到景物才没有变化。
我们的目的,就是通过一系列的矩阵变换,得到最终的取景变换矩阵V。
我们要得到取景变换矩阵V,说白了就是能够满足如下的条件:
pV=(0,0,0) 矩阵V将摄像机移动到世界坐标系的原点
rV=(1,0,0)矩阵V将摄像机的右向量与世界坐标系的x轴重合
uV=(0,1,0)矩阵V将摄像机的上向量与世界坐标系的y轴重合
lV=(0,0,1)矩阵V将摄像机的观察向量与世界坐标系的z轴重合
所以,想得到这个取景变换矩阵V,就是进行了先平移,后旋转。
摄像机操作:
1.平移:
将摄像机的位置向量p平移到原点就是实现这个式子:pV=(0,0,0),即摄像机的位置分量乘以V之后等于(0,0,0)。那么很简单,我们假设取景变换矩阵V实现平移操作的的中间矩阵为T来简化一下。而将摄像机的位置向量p平移到原点可以通过把他和它大小相等,方向相反的-p向量做加法轻松实现,即p-p=0,所以描述取景变换中的平移
2.旋转:
想要让摄像机的各分量与世界坐标系的各轴重合,即满足之前我们列出的这三个式子:
rV=(1,0,0)
uV=(0,1,0)
lV=(0,0,1)
实现起来,求出如下的一个3x3的矩阵A:
我们可以看出A是B矩阵的逆矩阵。而矩阵B刚好是个正交矩阵,那么因为:正交矩阵的逆矩阵等于其转置矩阵。也就是说B矩阵的逆矩阵等于B矩阵的转置矩阵,而B矩阵的逆矩阵就是A矩阵,那么就是说A矩阵等于B矩阵的转置矩阵。
那么我们求一下B矩阵的转置矩阵,就是求出A矩阵了。
也就是:
最后我们需要把A矩阵扩展成4X4的,然后计算一下两矩阵的值TA=V:
以上就是取景变换的求法也就是以前我们经常用到的D3DXMatrixLookAtLH函数的计算过程。
摄像机旋转实现:
实现摄像机的旋转,我们需要用到DX中的自带函数:
D3DXMATRIX *WINAPI D3DXMatrixRotationAxis(
D3DXMATRIX *pOut,
CONST D3DXVECTOR3 *pV,
FLOAT Angle
);
创建一个绕任意轴旋转的旋转矩阵。
参数:
pOut
[in, out] 指向D3DXMATRIX 结构的操作结果矩阵。
pV
[in] 指向任意轴向量。请参考 D3DXVECTOR3。
Angle
[in] 绕着任意轴旋转的角度(单位是弧度)。角度计算方法是当朝着旋转轴的原点看去时,顺时针方向为正值。
返回值:
指向绕着任意轴旋转的旋转矩阵。
说明:
函数返回值跟pOut 参数返回值是一样的。这样可以让函数D3DXMatrixRotationAxis作为其它函数的参数使用。
如果我们要绕向量(0.7,0.07,0.7)所确定的轴旋转90度:
D3DXMATRIX R;
D3DXVECTOR3 axis(0.7f, 0.7f, 0, 7f);
D3DXMatrixRotationAxis(&R, &axis, D3DX_PI / 2.0f);
摄像机的俯仰、偏航、滚动:
请先看以下几张图:俯仰:绕摄像机的right向量旋转图1
偏航:绕摄像机的up向量旋转图2
滚动:绕摄像机的look向量旋转图3
摄像机的升降、行走和扫视:
行走:沿着摄像机的观察方向(即:沿着向量look方向)的平动。
扫视:沿着right方向从一边走到另一边
升降:沿着up方向的平动。
附加注释代码
点击打开链接运行效果:
有问题的朋友请留言交流。
相关文章推荐
- Android Launcher桌面3D实现和原理分析
- DirectX 3D_实践之在DirectX3D中实现摄像机方位的动态变换
- CATransform3D 矩阵变换之立方体旋转实现细节
- 三维世界里的坐标和变换,逆方向旋转移动三维世界的方式来实现3D漫游
- Spring3.1.0实现原理分析(十三).MVC请求映射信息RequestMappingInfo详解
- 摄像机标定算法中的很多处理,都有道理。比如内参数矩阵的定义。实现了单位的归一化,使世界坐标的实际值不重要,单位也不重要,只是单位为1的方格。
- CATransform3D 矩阵变换之立方体旋转实现细节
- (转)从零实现3D图像引擎:(13)把宽高比、透视投影矩阵、屏幕变换矩阵说透
- CATransform3D 矩阵变换之立方体旋转实现细节
- Spring3.1.0实现原理分析(十三).MVC请求映射信息RequestMappingInfo详解
- CATransform3D 矩阵变换之立方体旋转实现细节 (转)
- 6.22 android计算字符高度宽度,红蓝3D图片的制作原理及NDK生成实现
- CATransform3D 矩阵变换之立方体旋转实现细节
- OpenGL中摄像机矩阵的计算原理
- osg::NodeVisitor中计算一个节点对应的世界变换矩阵、法向量、顶点坐标
- 摄像机、观察矩阵与取景变换
- CATransform3D 矩阵变换之立方体旋转实现细节
- CATransform3D 矩阵变换之立方体旋转实现细节
- 转置矩阵的分块并行乘法(C语言实现),计算矩阵C[rawn][rawn]=A[rawm][rawn]'*B[rawm][rawn],子块大小为S*T,其算法实现原理参加本代码的附件。
- 从零实现3D图像引擎:(13)把宽高比、透视投影矩阵、屏幕变换矩阵说透