AppleSeeker's Tech Blog
Welcome to AppleSeeker's space

如果你曾经用过一个摄像机,你所知道的最具动态的场景将在场景中有一个移动,不论是相机还是演员。在许多游戏中,操作相机的能力也同样重要。

移动相机来改变玩家在3D世界中看到的位置。相机使用View效果属性来实现的,并且我们其实一直在使用它,尽管在所有我们的3D示例工程中没有移动它。

在某些方面,有摄像头似乎不是很必要。毕竟,这似乎没有任何视觉上的不同在朝对象移动相机和朝相机移动对象。一旦我们开始构建复杂的有光照的多对象场景,然而,它变得非常方便来计算对象和光照坐标,而不必担心全部移动他们来模拟摄像头移动。

摄像机位置和方向

为了移动相机,我们必须去弄清楚如何设置视角矩阵所需要的摄像机坐标。幸运的是,XNA为我们很关注这个,并且提供一个非常有用的函数,CreateLookAt。构建一个视角矩阵例如随后呈现的对象将被定位,如果相机移动到所需要的位置。

CreateLookAt函数需要提供3块信息,都是关于Vector3结构体。所需要的值,按照函数所需要顺序,列在下面:
1)当前相机的位置作为在3D世界中的坐标(相机位置)
2)在相机中看到的坐标(目标位置)
3)告诉XNA哪个方向朝上的矢量(向上矢量)

这些值得前2个很容易理解。视图将会生成,因为当从相机位置直接朝目标位置看时,它将被看到。指定的目标位置将直接出现在渲染场景中心。向上矢量需要更多一点的说明。简单来说,它告诉XNA哪个方位是向上的(朝场景的最顶端)相对于摄像机位置。在多数情况下,你可以提供一个矢量简化沿着坐标y轴上的点:(0,1,0)。向上矢量不需要垂直于相机的视角方向。

有2种情况可能需要使用到一个不同的向上矢量值。第一种,如果我们想能够转动相机。转动相机围绕它的z轴以便它自己从世界的向上视角脱离视角的方法(180度转动相机将导致一切颠倒)。

下图显示我们早期导入的房子对象的三个视角。在这每一个视角中,房子有相同放置位置;它仅是相机的已经改变的向上矢量。左边是相机的向上矢量设置为(0,1,0)的视角,默认向上矢量。中间图形显示相机向上矢量为(0.5,0.5,0)的视角。相机已经转动到右边以便它的向上矢量正对上边和右边(好比你的头朝右边)。因此,房子似乎朝左边倾斜。在最后的图片中,相机的向上矢量是(1,0,0),所以是沿着坐标x轴向上。房子现在显示朝左边90度角方向旋转。

image

滚动相机可能不是在所有游戏中有用,但对于其中一些是非常便利的—任何游戏模仿飞机或宇宙飞船的移动,举例,将很可能想去使用它来允许飞行器倾斜到一边就像在飞行那样。

第二个解决办法对于不同向上矢量是必须的,当相机直接沿着y轴所看到的。如果相机直接向上看,我们将告诉它向前和向上是非常相同的方向。这并不真实,所以XNA的转换矩阵导致不会显示任何东西。

在其它情况下,XNA有非常宽容的值提供给向上矢量,将很好的应对非标准化的和不垂直于相机实现角度的矢量。

下面代码显示了一个CreateLookAt函数的简单调用,来设置相机以便它位于(0,5,5)位置,集中在坐标(0,0,0)位置,有一个向上矢量(0,1,0)。

Matrix  view = Matrix.CreateLookAt(new  Vector3(0, 5,  5), 
        new Vector3(0, 0, 0), 
        new  Vector3(0, 1,  0));

使用一些静态Vector3属性,这个代码就可以变得更可读些。

Matrix  view = Matrix.CreateLookAt(new Vector3(0, 5, 5), Vector3.Zero, Vector3.Up);

注意:不要忘了靠近和远离剪辑平面中已定义的可视区域。如果你移动相机足够接近或足够远离不属于这些剪辑平面的对象,它将从视角中消失。

这也也可以使用矩阵操作来设置相机位置,就像在我们的场景中我们为对象所做的。我们将看到在下一个部分如何去做。

posted on 2012-04-21 10:41  AppleSeeker(冯峰)  阅读(685)  评论(0编辑  收藏  举报