摄像机在3D游戏中,就类似于人类在现实生活中的眼睛,将眼前的事物映射到自己的脑海中,即在3D游戏中,将摄像机所能记录的场景人物全部显示在玩家眼前。
设计的用例图:
该摄像机系统拥有这些功能,开始设计类。
private:
//Save camera related matrices
D3DXMATRIX m_View;
D3DXMATRIX m_Proj;
D3DXMATRIX m_ViewProj;
//Relative to world space
D3DXVECTOR3 m_Pos;
D3DXVECTOR3 m_Right;
D3DXVECTOR3 m_Up;
D3DXVECTOR3 m_Look;
//Camera speed
float m_Speed;
//Frustum planes
D3DXPLANE m_FrustumPlanes[6]; // [0] = near
// [1] = far
// [2] = left
// [3] = right
// [4] = top
// [5] = bottom
定义了四个三维向量,分别是m_Pos代表摄像机的位置向量,m_Right代表向右向量,m_Up代表向上向量,m_Look代表观察向量。其中右向量,上向量以及观察向量,都必须是标准正交的。所谓正交——两个向量相互之间垂直,(u,v)=u_xv_x+u_yv_y+u_z*v_z=0,u⊥v。之所以使用标准正交向量,是因为在进行矩阵视图变化的时候,方便将这些向量插入到矩阵的某行中,方便矩阵的计算以及转换。
定义三个矩阵成员变量,为四阶矩阵,分别是m_View代表视图矩阵,m_Proj代表投影矩阵,m_ViewProj代表视图投影矩阵,目的是将方才的那些三维向量的值经过某些计算,再赋值到矩阵中。
使用矩阵一个原因是因为计算机底层硬件寄存器或者内存单元的分布是以行列式进行分布的,这类似于矩阵,所以使用矩阵进行计算会方便和提高效率;其次是为了使矩阵所表达的意思更加有意义,如当摄像机进行移动时,m_Pos发生变换,经过计算m_View和m_Proj矩阵也会进行变化,但当进行变化时,如何判断该变化是否是玩家或者开发人员需要的效果,这时就需要对矩阵中的值进行解析判断,对第四行的值进行解析,如[v1,v2,v3,w],其中v1,v2,v3是摄像机的相关信息,而w代表着其他含义,w为1时,代表着当前所执行的操作是平移操作,且平移变化正确无误;w为0时,代表着无法对向量进行平移变换,变换失效。
m_Speed代表着摄像机的移动速度,m_FrustumPlanes代表着立方体的六个面,用于判断摄像机所表现的景象里面,哪些可见,哪些不可见,有助于渲染多个物体时,提高性能。
通过判断在3D游戏中的物体是否在此平截头体中,如果是则进行渲染,反之,不进行渲染。
计算视图矩阵
当玩家输入按键时,游戏需要对玩家的按键作出一定的反应,如玩家输入前进键,那么游戏应该向前前进,那么摄像机系统也应该进行更新与计算视图矩阵。
现设向量P=(px,py,pz),R=(rx,ry,rz),U=(ux,uy,uz),D=(dx,dy,dz)分别表示位置(position),右(right),向上(up)和观察(look)。变化矩阵V。
矩阵相乘意义:
值 | 意义 |
---|---|
PV=(0,0,0) | 将摄像机移到世界坐标系原点 |
RV=(1,0,0) | 将摄像机的right向量与世界坐标系的X轴重合 |
UV=(0,1,0) | 将摄像机的up向量与世界坐标系的Y轴重合 |
DV=(0,0,1) | 将摄像机的look向量与世界坐标系的Z轴重合 |
步骤:
(1)平移
需将摄像机的位置从p移动到原点,那么则减去p即可到达原点,即p-p=0。
矩阵表示
坐标图显示
平移前
其中A,B,D分别表示为3D坐标内的物体,而E表示的摄像机,用蓝色的框进行表示。
平移到原点后
需注意的是,当摄像机E平移至原点后,在3D坐标系中的其他物体也会随着平移,这样才能是摄像机的视角保持不变。
(2)旋转
设置一个旋转矩阵A,使之与各个方向的向量相乘得到表4-1中的值。
RA=[1,0,0] UA=[0,1,0] DA=[0,0,1]
求解矩阵A的值,由于三个关系式中都含有系数A,那么可以这样设置
那么
显然可以看出A其实就是B的逆矩阵(BA=BB-1=1),且矩阵B是标准正交矩阵,所以其逆矩阵与转置矩阵相等。
立即推:B-1=BT=A=
其中为BT转置矩阵。
(3)变为完整的视图矩阵V
T为第一步的平移矩阵,A为第二步的旋转矩阵。
源代码详解