我在Direct3D中乘以矩阵以获得结果时收到了两个相互矛盾的答案。教程会声明从左到右相乘,这很好,但不是我想象它的方式。
以下是一个例子:
OpenGL(从上到下阅读):
GLRotatef(90.0f);
GLTranslatef(20.0f,0,0);
因此,您可以看到旋转30度的世界轴。然后你在现在旋转的x轴上平移20.0,看起来你正在世界y轴上升。
在Direct3D中,执行:
wm = rotatem * translatem;
是不同的。看起来这个物体只是在原点处旋转并在世界的x轴上平移,因此它向右移动而不是向上移动。只有在我颠倒顺序并从右到左阅读时它才有效。
另外,例如,在frank luna关于DX10的书中,他将介绍如何进行镜像反射。我得到了所有这一切,但是当他这样做时:
reflection_matrix = world_m * reflection_m;
答案 0 :(得分:9)
问题在于您将矩阵乘以使复合变换矩阵与其应该相反的顺序。您正在执行:wm = rotatem * translatem
,它遵循您为OpenGL执行的操作的顺序,但对于DirectX,矩阵应该是wm = translatem * rotatem
OpenGL和DirectX之间的根本区别在于OpenGL以列主要顺序处理矩阵,而DirectX以行主顺序处理matric。
要从专业列转到行专业,您需要找到OpenGL矩阵的转置(交换行和列)。
所以,如果你在OpenGL中编写wm = rotatem * translatem
,那么你想要为DirectX转置它,即:
wmT = (rotatem*translatem)T = translatemT * rotatemT
这解释了为什么在DirectX中必须反转矩阵乘法的顺序。
答案 1 :(得分:1)
见this answer。在OpenGL中,每个后续操作都是它之前所有操作的预乘,而不是后乘。您可以将矢量的矩阵乘法视为函数评估。
如果你想要的是首先旋转一个矢量,然后翻译你在OpenGL中解决的旋转矢量,首先调用glRotatef
然后调用glTranslatef
,你可以用函数来表达打电话为
myNewVector = translate(rotate(myOldVector))
rotate
函数执行此操作
rotate(anyVector) = rotationMatrix * anyVector
并且translate
函数执行此操作
translate(anyOtherVector) = translationMatrix * anyOtherVector
所以使用矩阵乘法的等效表达式看起来像
myNewVector = translationMatrix * rotationMatrix * myOldVector
也就是说,您的组合转换矩阵看起来像translationMatrix * rotationMatrix
。