Learn OpenGL In Qt之摄像机

在这里插入图片描述

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~
公众号: C++学习与探索  |  个人主页: rainInSunny  |  个人专栏: Learn OpenGL In Qt


  我们知道改变观察矩阵可以移动场景,为了更好描述场景移动,一般会模拟出一个摄像机。场景向后移动相当于摄像机向前移动,通过这种相对性可以产生一种我们在移动而不是场景在移动的感觉。

摄像机/观察空间

  当我们讨论摄像机/观察空间(Camera/View Space)的时候,是在讨论以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向的观察坐标。要定义一个摄像机,我们需要它在世界空间中的位置、观察的方向、一个指向它右侧的向量以及一个指向它上方的向量。实际上创建了一个三个单位轴相互垂直的、以摄像机的位置为原点的坐标系。
在这里插入图片描述

摄像机位置

  获取摄像机位置很简单。摄像机位置简单来说就是世界空间中一个指向摄像机位置的向量。不要忘记正z轴是从屏幕指向你的,如果我们希望摄像机向后移动,我们就沿着 z 轴的正方向移动。

QVector3D cameraPos(0.0f, 0.0f, 3.0f);

摄像机方向

  下一个需要的向量是摄像机的方向,这里指的是摄像机指向哪个方向。现在我们让摄像机指向场景原点:(0, 0, 0)。将两个矢量相减,我们就能得到这两个矢量的差,用场景原点向量减去摄像机位置向量的结果就是摄像机的指向向量。由于我们知道摄像机指向 z 轴负方向,但我们希望方向向量(Direction Vector)指向摄像机的 z 轴正方向。如果我们交换相减的顺序,我们就会获得一个指向摄像机正 z 轴方向的向量:

QVector3D cameraTarget(0.0f, 0.0f, 0.0f);
QVector3D cameraDirection = cameraPos - cameraTarget;
cameraDirection.normalize();

右轴

  需要的另一个向量是一个右向量(Right Vector),它代表摄像机空间的 x 轴的正方向。为获取右向量需要先使用一个小技巧:先定义一个上向量(Up Vector)。接下来把上向量和第二步得到的方向向量进行叉乘。两个向量叉乘的结果会同时垂直于两向量,因此会得到指向 x 轴正方向的那个向量(如果我们交换两个向量叉乘的顺序就会得到相反的指向 x 轴负方向的向量):

QVector3D up(0.0f, 1.0f, 0.0f);
QVector3D cameraRight = QVector3D::crossProduct(up, cameraDirection);
cameraRight.normalize();

上轴

  现在已经有了 x 轴向量和 z 轴向量,获取一个指向摄像机的正 y 轴向量就相对简单了,把右向量和方向向量进行叉乘:

QVector3D cameraUp = QVector3D::crossProduct(cameraDirection, cameraRight);

  在叉乘和一些小技巧的帮助下,我们创建了所有构成观察/摄像机空间的向量。使用这些摄像机向量我们就可以创建一个 LookAt 矩阵了,它在创建摄像机的时候非常有用。

Look At

  使用矩阵的好处之一是如果你使用 3 个相互垂直的轴定义了一个坐标空间,可以用这 3 个轴外加一个平移向量来创建一个矩阵,并且你可以用这个矩阵乘以任何向量来将其变换到那个坐标空间。这正是 LookAt 矩阵所做的,现在有了 3 个相互垂直的轴和一个定义摄像机空间的位置坐标,可以创建我们自己的 LookAt 矩阵了:

L o o k A t = [ R x R y R z 0 U x U y U z 0 D x D y D z 0 0 0 0 1 ] ∗ [ 1 0 0 − P x 0 1 0 − P y 0 0 1 − P z 0 0 0 1 ] LookAt=\begin{bmatrix} R_x& R_y& R_z& 0\\ U_x& U_y& U_z& 0\\ D_x& D_y& D_z& 0\\ 0& 0& 0& 1\end{bmatrix} * \begin{bmatrix} 1& 0& 0& -P_x\\ 0& 1& 0& -P_y\\ 0& 0& 1& -P_z\\ 0& 0& 0& 1\end{bmatrix} LookAt= RxUx

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值