本文基于一个Qt opengl实现的效果来解释 view-matrix的推导
1、实现的案例
2、代码简析
关于模型和纹理的读取暂且略过
在paintgl里,设置相机在xoy平面绕原点,轴长为10的旋转,旋转的水平角度输入是经过的时间(秒)
float time = m_time.elapsed() / 1000.0;
const float distance = 10.0f;
float camX = sin(time) * distance;
float camZ = cos(time) * distance;
计算相机的direction,right,top向量,用这三个向量构成一个标准正交基
cameraPos = QVector3D(camX,0.0f,camZ);
cameraTarget = QVector3D(0.0f,0.0f,0.0f);
cameraDirection = QVector3D(cameraPos - cameraTarget);
cameraDirection.normalize();
QVector3D up = QVector3D(0.0f ,1.0f, 0.0f);
cameraRight = QVector3D::crossProduct(up,cameraDirection);
cameraRight.normalize();
cameraUp = QVector3D::crossProduct(cameraDirection,cameraRight);
cameraUp.normalize();
3、view-matrix分析
空间中任意一个点的坐标本质上是在基的方向上的偏移量,是相对于原点偏移量的体现,在直角坐标系 下的任意一点可以被分解为:
,即基与坐标的表示法,也可以表示世界坐标系,接下来我们站在世界坐标系的角度看这个问题

我们前面求出了right,top,direction,是相机空间的坐标系,在世界坐标系的角度下来看,相机坐标系整个发生了位移,即计算的是相对于原点的偏移量,原点是相机,设相机位置为
,还需要加上
,所以有如下式子:
x'y'z'是在相机坐标系下的坐标,这里是要求矩阵的逆的,但由于是正交矩阵,直接转置即可
代码如下:
QMatrix4x4 trans;
trans.translate(QVector3D(-cameraPos.x(),-cameraPos.y(),-cameraPos.z()));
QMatrix4x4 view(
cameraRight.x(), cameraRight.y(), cameraRight.z(),0,
cameraUp.x(), cameraUp.y(), cameraUp.z(),0,
cameraDirection.x(), cameraDirection.y(), cameraDirection.z(),0,
0, 0, 0, 1
);
view = view*trans;