矩阵/向量乘法顺序

时间:2015-06-05 22:22:04

标签: opengl math matrix vector

我在线阅读了十几篇关于OpenGL中旋转,平移和缩放矩阵乘法的正确顺序的文章。然而,既然我自己开始实施它,我就到了我真的很困惑的地步。

让我们假设在我的代码中我计算变换矩阵,并且我将它作为一个结果矩阵传递给着色器:

shader.SetUniform("u_Matrix", scale * rotation * translation);

在顶点着色器中,我将顶点乘以这个矩阵:

gl_Position = u_Matrix * vec4(a_Position, 0.0, 1.0);

现在,按照这个顺序(缩放*旋转*翻译),我得到的正是我想要的: 我旋转对象,然后将其移动到特定点,然后我缩放它。 有人可以解释一下为什么这是正确的顺序?

我一直认为所有的变换都是从矢量方面应用的#34;

例如,如果我们"扩展"乘法:

gl_Position = scale * rotation * translation * vec4(a_Position, 0.0, 1.0);

然后首先应该应用平移,然后是旋转和之后的比例。如果不是翻译和轮换的顺序,那么对我来说一切似乎都没问题。如果我们不想围绕某个点旋转,我们应该首先旋转然后翻译,这不是这里的情况。

为什么这种转变按预期工作?

1 个答案:

答案 0 :(得分:2)

您的C ++矩阵可能存储为行主要内容。这意味着将它们从左到右相乘是一个“原点”转换,而从右到左则是一个“局部”增量转换。

然而,

OpenGL使用列主要排序内存布局(16个元素数组中的第13,14和15个元素被视为转换组件)。

要在OpenGL中使用行主矩阵,您可以执行以下两项操作:

  1. glUniformMatrix *函数,有一个参数将GL_TRUE传递给转置:
  2. void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose , const GLfloat *value);

    这将重新安排他们成为专栏。

    1. 另一种方法是恢复着色器中的操作顺序:
    2. gl_Position = vec4(a_Position, 0.0, 1.0) * u_Matrix;

      但是你会发现大多数GLSL文献都会使用从左到右的本地主要排序,因此最好坚持下去。

      另一个替代方法是更改​​C ++端的布局以使其成为主要列(但我个人认为行主要是要处理那里)。