在我的 Direct3D 应用程序中,可以使用鼠标或箭头键移动相机。但是,如果我将 (0,1,0) 硬编码为 中的向上方向向量LookAtLH
,则该帧在相机的某些方向上会变为空白。
我刚刚了解到,当沿 Y 轴看时,(0,1,0) 不再作为向上方向工作(似乎很明显?)。对于这些特殊情况,我正在考虑将我的向上方向切换到其他方向。有没有更优雅的方法来处理这个?
假设您可以计算一个指向前方的向量(您正在查看的内容 - 您的位置)和一个指向右侧的向量(除非您可以滚动,否则始终在 XZ 平面上)。对这两个向量进行归一化,然后向上 x 向右(其中 x 是叉积)。
通常,您可以将偏航、俯仰和滚动插入旋转矩阵并旋转轴矢量以向右、向上和向前,但我想这就是您使用 LookAtLH 来避免的。
见http://en.wikipedia.org/wiki/Rotation_matrix#The_3-dimensional_rotation_matricies
处理这个问题的优雅方法是使用 Unit Quaternions。四元数是 4 个值的向量,它编码 3D 空间中的方向(不是某些文章声称的旋转),单位四元数是向量长度 sqrt(x^2+y^2+z^2+w^ 2) 为 1.0。有一组用于处理四元数的数学运算,类似于使用矩阵对旋转进行编码,另外还有一个好处是四元数永远不能表示退化的方向。当您需要将结果提供给 GPU 时,您可以自由地将四元数转换为 3x3 或 4x4 矩阵。
你的问题是,当你移动你的相机时,你会在相机的向上方向引入一点扭曲。通过强制相机在每次迭代时将自身重新定位在 (0,1,0) 向量上,实际上是在旋转相机,然后夹紧相机的方向以保持在球体的表面上,但是当您的相机碰到这个球体的极点没有很好的方向来调用“向上”,并且您的矩阵变为奇异并为您提供零大小的多边形(因此是黑屏)。四元数有能力通过这些极点进行插值并很好地从另一边出来,让您始终拥有一个有效的矩阵。你所要做的就是控制“扭曲”。
要测量这种扭曲,您应该阅读《Graphics Gems 4》一书中 Ken Shoemake 的文章“减少光纤束扭曲”。他展示了一种测量这种累积扭曲的好方法,以及如何在它令人反感时将其移除。