重看DX龙书,发现之前想不通的地方居然一下就懂了,可能是我太笨,把一些简单问题搞复杂了。
本文记录的是我对取景变换的一些心得。
首先要弄清楚相机代表什么
其实它就是我们的眼睛,因为最终绘制出来的东西,就是相机视野中的对象。
取景变换,就是要把物体从世界坐标系变换到观察坐标系(即相机空间)中来。取景变换可以分为两个步骤:
1、在世界坐标系中使所有对象跟着相机平移,将相机移至坐标原点。注意,是使所有对象跟着相机平移。
2、使所有对象跟着相机旋转,使得相机观察方向为Z轴正方向,并且相机的UP向量指向Y轴正方向。
由于是所有对象随着相机一起移动,那对象相对于相机的位置,在移动后和移动前是一致的,那么为什么要还要进行取景变换呢?
答案是为了方便固定渲染流水线的下一个步骤,即投影变换。
因为投影变换中要进行线性插值,将相机的视域体(Frustum)变成一个叫做规则观察体CVV(Canonical View Volume)的长方体,而后者非常便于裁剪。
关于透视投影变换,请参考《深入探索透视投影变换(续)》。
第2步中,之所以使相机的UP向量指向Y轴正方向,是因为UP向量指向Y轴负方向时,相机的观察方向也是Z轴正方向,但观察到的对象是颠倒的。
这就是D3DXMatrixLookAtLH函数中的基准向量参数传递(0,1,0)的原因。
讲过这两步仿射变换,对象的坐标已经与其在世界坐标系中的坐标不同了,新的坐标系就是观察坐标系。
在观察坐标系中,相机的坐标与观察方向是固定的,而其他对象是可以移动的。但是现实中人是可以移动的,人可以走近一个物体以观察的更仔细,也可以转身看到背后的世界。而观察坐标系中的固定相机是无法完成这些的,那怎么办?
答案就是实现一个摄像机类。这个摄像机类有4个向量成员:位置向量、UP向量、RIGHT向量以及LOOk向量。这个相机可以沿着UP向量、RIGHT向量和LOOK向量平移,也可以绕着它们旋转。在这个相机运动之后(其他物体不随相机运动),可以根据这四个向量计算出一个观察矩阵,将它设为D3D的观察矩阵,就等于实现了相机的移动。