我将通过这两种方法来计算lookat矩阵
- D3DXMatrixLookAtLH
zaxis = 正常(在 - 眼睛)
xaxis = normal(cross(up, 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
-点(x轴,眼睛) -点(yaxis,眼睛) -点(zaxis,眼睛)1
- D3DXMatrixLookAtRH
zaxis = 正常(眼睛 - 在)
xaxis = normal(cross(up, 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
点(x轴,眼) 点(y轴,眼) 点(z轴,眼) 1
为什么 RH 的转换没有乘以 -1?
TL;DR:D3DXMatrixLookAtRH
的Microsoft文档页面是错误的。我已经提交了 PR 来修复它。
在D3DXMath的实际实现中,很明显,在这两种情况下,都应该为LH和RH-dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye)
转换。
唯一的区别是zaxis计算。
D3DXMATRIX* WINAPI D3DXMatrixLookAtRH
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
const D3DXVECTOR3 *pUp )
{
D3DXVECTOR3 XAxis, YAxis, ZAxis;
// Compute direction of gaze. (-Z)
D3DXVec3Subtract(&ZAxis, pEye, pAt);
D3DXVec3Normalize(&ZAxis, &ZAxis);
// Compute orthogonal axes from cross product of gaze and pUp vector.
D3DXVec3Cross(&XAxis, pUp, &ZAxis);
D3DXVec3Normalize(&XAxis, &XAxis);
D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);
// Set rotation and translate by pEye
pOut->_11 = XAxis.x;
pOut->_21 = XAxis.y;
pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);
pOut->_12 = YAxis.x;
pOut->_22 = YAxis.y;
pOut->_32 = YAxis.z;
pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);
pOut->_13 = ZAxis.x;
pOut->_23 = ZAxis.y;
pOut->_33 = ZAxis.z;
pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);
pOut->_14 = 0.0f;
pOut->_24 = 0.0f;
pOut->_34 = 0.0f;
pOut->_44 = 1.0f;
return pOut;
}
D3DXMATRIX* WINAPI D3DXMatrixLookAtLH
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
const D3DXVECTOR3 *pUp )
{
D3DXVECTOR3 XAxis, YAxis, ZAxis;
// Compute direction of gaze. (+Z)
D3DXVec3Subtract(&ZAxis, pAt, pEye);
D3DXVec3Normalize(&ZAxis, &ZAxis);
// Compute orthogonal axes from cross product of gaze and pUp vector.
D3DXVec3Cross(&XAxis, pUp, &ZAxis);
D3DXVec3Normalize(&XAxis, &XAxis);
D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);
// Set rotation and translate by pEye
pOut->_11 = XAxis.x;
pOut->_21 = XAxis.y;
pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);
pOut->_12 = YAxis.x;
pOut->_22 = YAxis.y;
pOut->_32 = YAxis.z;
pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);
pOut->_13 = ZAxis.x;
pOut->_23 = ZAxis.y;
pOut->_33 = ZAxis.z;
pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);
pOut->_14 = 0.0f;
pOut->_24 = 0.0f;
pOut->_34 = 0.0f;
pOut->_44 = 1.0f;
return pOut;
}
D3DXMatrixLookAtRH
和D3DXMatrixLookAtLH
都是"D3DXMath"的一部分,D3DXMath是D3DX9和D3DX10中包含的数学库。这些帮助程序库已弃用,DirectX SDK 本身也是如此。建议改用 DirectXMath。
如果出于某种原因必须使用 D3DX9,请注意,只需使用 Microsoft.DXSDK.D3DX NuGet 即可避免混合使用旧版 DirectX SDK 和现代版 Visual Studio 的文档Microsoft Docs 上涵盖的所有复杂问题。新项目应移至各种替换中的任何一个。有关更多详细信息,请参阅此博客文章。