OpenGL实例教程11:摄像机空间
目前已经学习了两种类型的转换:
1、位移变换:将模型放置在3D世界的任何地方。
2、透视投影变换:它将3D世界中的一个顶点的位置投影到2D世界(即平面)。
摄像机的位置如何处理?
默认位于3D空间的原点。
需要可以将相机放置在任何地方,并将顶点投影到它前面的某个2D平面上。
在下面的图片中,相机背对着我们。在它前面有一个虚拟的2D平面,球被投射到这个平面。相机是倾斜的,所以平面也相应倾斜。由于摄像机的视角受到其视场角的限制,2D平面的可见部分是矩形,其他部分都将被剪掉。矩形内容将显示在屏幕上。

理论上,可以使用一种转换将3D世界中的对象投射到(任意位置、角度的)相机前面的2D平面上。然而,这会比之前的运算复杂得多。如果相机位于原点保持不变,以反方向移动场景中的其他物体,将允许我们使用已经学过的方法正确地渲染场景。

需要添加两个新的转换,并将它们插入到已经拥有的转换管道中:
相机移动到原点,移动对象,使它们与相机的相对位置保持不变。
将对象从相机转向相反的方向转动。
移动摄像机非常简单。如果相机位于(x,y,z),那么平移变换为(-x, -y, -z)。变换矩阵如下图所示:

下一步是处理相机的旋转。需要相机空间坐标系统中找到物体顶点的新坐标。所以实际的问题是:如何从一个坐标系转换到另一个坐标系?
首选需要确定两个坐标系的基底:
以右图为例:世界坐标系由三个线性无关的单位向量(1,0,0)、(0,1,0)和(0,0,1)定义。这意味着这三个向量中的任何一对向量定义了一个垂直于第三个向量的平面(例如:平面XY永久垂直于Z轴等)。很容易看出,摄像机坐标系是由向量(1,0,-1),(0,1,0),(1,0,1)定义的。对这些向量进行归一化后,我们得到(0.7071,0,-0.7071)、(0,1,0)和(0.7071,0,0.7071)。

接下来就通过世界坐标的位置投影到相机世界坐标,首选需要两个概念:
“标量投影”:任意向量a和单位向量B的点积的结果,是a在向量B方向上的大小,即向量a在向量B上的投影。
“UVN相机”:
N:摄像机到目标的向量,对应于Z轴。
V :向上的向量。对于飞行模拟器来说,如果飞机是反向的,那么这个向量很可能指向地面。对应于Y轴。
U :从相机指向它的右侧。它对应于X轴。
世界坐标到相机坐标需要在位置和UVN向量之间执行点积操作。使用矩阵即可:

主要代码:
运行效果:
