与GLSL和GLM之间的矩阵数学不一致,或者是否存在"坏"视图矩阵

时间:2015-04-11 10:35:29

标签: c++ opengl matrix glsl glm-math

所以,我在GLSL和GLM之间遇到了一些奇怪的事情。

如果我生成以下视图矩阵(C ++):

vec3 pos(4, 1, 1);
vec3 dir(1, 0, 0);
mat4 viewMat = glm::lookAt(pos, pos+dir, vec3(0,0,1));

然后,在glsl中,执行:

fragColour.rgb = vec3(inverse(viewMat) * vec4(0,0,0,1)) / 4.f;

然后我希望屏幕变成粉红色或(1.0,0.25,0.25)。相反,我变黑了。

如果我在GLM中这样做,那么:

vec3 colour = vec3(glm::inverse(viewMat) * vec4(0,0,0,1)) / 4.f;
cout << glm::to_string(colour) << endl;

我得到期望的结果(1.0,0.25,0.25)。

现在,如果我将viewMat更改为(C ++):

vec3 pos(4, 1, 1);
vec3 dir(1, 0.000001, 0);
mat4 viewMat = glm::lookAt(pos, pos+dir, vec3(0,0,1));

然后是bam!我在GLSL和GLM中得到(1.0,0.25,0.25)。

这对我没有意义。为什么这样做?这个视图矩阵在GLSL中的其他任何地方都可以正常工作 - 我只是无法反转它。只要dirY == 0.f。

就会发生这种情况

另外,请提出问题标题的改进建议,我不确定它应该是什么。

编辑:此外,它似乎与lookAt的向上向量(无论如何我设置为Z)有任何关系。即使我设置为(0,1,0),也会发生同样的事情。一切都转向侧面,但我仍然无法反转GLSL中的视图矩阵。

编辑:好的,所以在derhass的建议中,我尝试发送倒置的视图矩阵。 Bam,效果很好。所以,似乎我的GL实现确实无法反转该矩阵。这很容易成为我遇到的最奇怪的GL错误。但是,为什么在着色器中反转矩阵是一个坏主意的某种解释将是值得赞赏的。 EditAgain:在我的引擎中发送倒置矩阵导致了巨大的帧率提升。绝对做到了。

1 个答案:

答案 0 :(得分:4)

任意4x4矩阵求逆不是一项快速而安全的任务

由于许多原因,例如GPU侧的FPU精度较低以及反演期间需要多次划分(这取决于计算方法),并非所有矩阵都有逆等(我认为这也是GL的原因)也没有这样的实现)...为了获得更好的图像,请参阅Understanding 4x4 homogenous transform matrices并查找matrix_inv函数,计算实际上有多复杂(它使用决定因素)。还有GEM(高斯消除方法),但由于其怪癖和需要排序行而未使用...

如果矩阵每帧渲染是静态的,通常就是这样,浪费GPU功率在Vertex / Fragment / Geometry着色器中反复计算每个Vertex / Fragment(这就是速度提升的原因)

有人可能反对orthogonal homogenous matrix反转只是转置矩阵,但是GL / GLSL如何知道它处理这样的矩阵(检查也不是那么简单)无论如何,在这种情况下你可以使用{{ 1}}在GLSL中实现,应该很快(它只是元素的重新排序)