0

在 MSDN(http://msdn.microsoft.com/en-us/library/windows/desktop/bb281710%28v=vs.85%29.aspx)上,LookAt 函数是这样的数学:

zaxis = normal(cameraTarget - cameraPosition)
xaxis = normal(cross(cameraUpVector, zaxis))
yaxis = cross(zaxis, xaxis)

xaxis.x           yaxis.x           zaxis.x          0
xaxis.y           yaxis.y           zaxis.y          0
xaxis.z           yaxis.z           zaxis.z          0
-dot(xaxis, cameraPosition)  -dot(yaxis, cameraPosition)  -dot(zaxis, cameraPosition)  1

据我所知,最后一行是翻译。您能否解释一下为什么不能只将 cameraPosition 放在这一行并且需要 dot 函数?

4

1 回答 1

4

这是因为 View 矩阵将对象从世界空间转换到相机空间。将相机放置在其位置的不是转换。这将是逆变换。考虑一个简单的二维坐标系:

坐标系

黑色坐标系是世界系统。蓝色的是带有系统的相机。绿色箭头是相机在世界空间中的平移向量。

视图矩阵会将相机从其当前位置放回原点。第一步是旋转,使两个系统的相应轴指向同一方向:

坐标系变换

这是通过矩阵的其他条目(m_11 到 m_33)来实现的。

现在只剩下一个翻译了。但是平移向量被转换了。幸运的是,我们知道,如何。平移向量等于相机位置(注意,DirectX 使用转置矩阵。为了显示背后的数学,我将它们转回):

/ xAxis.x   xAxis.y  xAxis.z   ...\    / camPos.X \   / camPos.x * xAxis.x + camPos.Y * xAxis.y + camPos.z * xAxis.z \
| yAxis.x   yAxis.y  yAxis.z   ...|    | camPos.Y |   | camPos.x * yAxis.x + camPos.Y * yAxis.y + camPos.z * yAxis.z |
| zAxis.x   zAxis.y  zAxis.z   ...|  * | camPos.Z | = | camPos.x * zAxis.x + camPos.Y * zAxis.y + camPos.z * zAxis.z |
\    0        0         0      .../    \    0     /    \                       0                                     /

如果你看看结果:

camPos.X * xAxis.x + xamPos.Y * xAxis.y + camPos.z * xAxis.z

然后你会看到这等于

dot ( camPos, xAxis)

最后,点积用于补偿旋转。没有它,相机会有些位移(在示例中右上角太远)。

于 2012-07-10T23:09:12.647 回答