我在线阅读了十几篇关于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);
然后首先应该应用平移,然后是旋转和之后的比例。如果不是翻译和轮换的顺序,那么对我来说一切似乎都没问题。如果我们不想围绕某个点旋转,我们应该首先旋转然后翻译,这不是这里的情况。
为什么这种转变按预期工作?
答案 0 :(得分:2)
您的C ++矩阵可能存储为行主要内容。这意味着将它们从左到右相乘是一个“原点”转换,而从右到左则是一个“局部”增量转换。
然而,OpenGL使用列主要排序内存布局(16个元素数组中的第13,14和15个元素被视为转换组件)。
要在OpenGL中使用行主矩阵,您可以执行以下两项操作:
void glUniformMatrix4fv(GLint location, GLsizei count,
GLboolean transpose , const GLfloat *value);
这将重新安排他们成为专栏。
gl_Position = vec4(a_Position, 0.0, 1.0) * u_Matrix;
但是你会发现大多数GLSL文献都会使用从左到右的本地主要排序,因此最好坚持下去。
另一个替代方法是更改C ++端的布局以使其成为主要列(但我个人认为行主要是要处理那里)。