【发布时间】:2016-10-01 00:01:33
【问题描述】:
我目前正在学习 OpenGL 和 GLSL,以编写一个简单的软件来加载模型、在屏幕上显示、转换它们等。
作为第一阶段,我编写了一个不使用 OpenGL 的纯 C++ 程序。 它工作得很好,而且它使用行主矩阵表示:
例如 mat[i][j] 表示第 i 行和第 j 列。
class mat4
{
vec4 _m[4]; // vec4 is a struct with 4 fields
...
}
这是相关的矩阵乘法方法:
mat4 operator*(const mat4& m) const
{
mat4 a(0.0);
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
for (int k = 0; k < 4; ++k)
{
a[i][j] += _m[i][k] * m[k][j];
}
}
}
return a;
}
为了从模型空间到剪辑空间,我在 C++ 中执行以下操作:
vec4 vertexInClipSpace = projectionMat4 * viewMat4 * modelMat4 * vertexInModelSpace;
现在,尝试在 GLSL 着色器(1.5 版)中实现它会产生奇怪的结果。它有效,但前提是我 post 将顶点相乘而不是预乘它,并且另外转置每个矩阵。
uniform mat4 m;
uniform mat4 v;
uniform mat4 p;
void main()
{
// works ok, but using post multiplication and transposed matrices :
gl_Position = vec4(vertex, 1.0f) * m * v * p;
}
虽然 v2 = P * V * M * v1 与 transpose(v2) = transpose(v1) * transpose(M) * transpose(V) * transpose(P) 在数学上是一样的,
我显然没有得到任何东西,因为我什至没有看到他们在顶点着色器中发布乘法顶点的 1 个参考。
总结一下,具体问题如下:
- 为什么会这样?在 glsl 中发布乘法是否合法?
- 如何传递我的 C++ 矩阵,以便它们在着色器中正常工作?
相关问题的链接:
编辑:
问题通过改变调用中的“转置”标志来“解决”:
glUniformMatrix4fv(
m_modelTransformID,
1,
GL_TRUE,
&m[0][0]
);
现在着色器中的乘法是预乘:
gl_Position = MVP * vec4(vertex, 1.0f);
哪一种让我感到困惑,因为数学对于作为行主矩阵转置的列主矩阵没有意义。
谁能解释一下?
【问题讨论】: