这篇blog写的是观察空间(从世界空间到观察空间)里的观察矩阵(view matrix),也称之为摄像机(camera)。

本质上来说,并不存在什么摄像机。所谓对空间的观察,实际上是物体自己在变换(反方向变换),造成一种我们人为观测的感觉,这也就是观察矩阵的功能:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向的观察坐标。


不过姑且还是称之为摄像机吧(camera)。

要确定一个摄像机的位置,需要有三个向量。

第一个是指向摄像机位置的向量(基于世界坐标)。

第二个是摄像机的方向向量,也就是摄像机指向的位置(target)的相反向量,实际上,这里用方向向量这个名字并不是很合适,因为实际上这个向量与实际方向向量是相反的。(ps:也既是摄像机的z正半轴)

第三个就是上向量(上轴,基于观察坐标),上向量的确定稍微麻烦一些,首先我们先人为定义一个上向量(基于世界坐标),然后把上向量和方向向量进行叉乘得到一个右向量(指向x正半轴,基于观察坐标),接着将这个右向量(x)与方向向量(z)进行叉乘,就得到了上向量(指向y正半轴,基于观察坐标)。

得到这三个轴向量之后,我们便可以使用这三个轴(确定一个坐标空间)外加一个平移向量来创建一个变换矩阵,我们可以通过这个变换矩阵乘以任何向量来变换到这个坐标空间。而OpenGL让我们免除了上面的繁琐过程,它提供了一个函数lootAt,让我们免除了上面的繁琐步骤。

glm::mat4 view = glm::mat4(1.0f);

view = glm::lookAt(cameraPos, Target, Up);
//(位置,目标位置,上向量)

别小看这几个参数,它可以让我们玩出点花来。举个栗子,对于cameraPos,我们可以创建一个基于系统时间变化的圆形(y轴不动,xz轴改变),即在每一帧改变x, z坐标,这样子摄像机就会围着目标点旋转了;而对于Target,如果让他随着cameraPos的改变来改变,那么摄像机就可以达到平移的效果。


上面讲的是焦点(Target)不动,或者随着cameraPos同步变化的情况,接下来讲讲cameraPos不动,焦点(Target)变化的情况。

首先我们需要引入 欧拉角(Euler Angles)的概念,欧拉角有三种,分别是俯仰角(pitch), 偏航角(yaw), 滚转角(roll)。更加具体,详细的概念参照博客最后给出来的链接。

之后便可通过运算更新Target的值,来达到fps游戏鼠标上下左右移动视角的效果。

参考:

[1]如何通俗地解释欧拉角,之后为什么引入四元数?

01-20 00:59