Jag*_*oly 5 c++ opengl glsl matrix 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));
Run Code Online (Sandbox Code Playgroud)
然后,在glsl中,执行:
fragColour.rgb = vec3(inverse(viewMat) * vec4(0,0,0,1)) / 4.f;
Run Code Online (Sandbox Code Playgroud)
然后我希望屏幕变成粉红色,或(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;
Run Code Online (Sandbox Code Playgroud)
我得到了期望的结果(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));
Run Code Online (Sandbox Code Playgroud)
然后bam!我在GLSL和GLM中得到(1.0,0.25,0.25).
这对我来说毫无意义.为什么这样做?这个视图矩阵在GLSL中的其他任何地方都可以正常工作 - 我只是无法反转它.只要dirY == 0.f,就会发生这种情况.
另外,请提出问题标题的改进建议,我不确定它应该是什么.
编辑:此外,它似乎与lookAt的向上向量(我设置为Z无论如何)有任何关系.即使我设置为(0,1,0),也会发生同样的事情.一切都转向侧面,但我仍然无法反转GLSL中的视图矩阵.
编辑:好的,所以在derhass的建议中,我尝试发送倒置的视图矩阵.Bam,效果很好.所以,似乎我的GL实现确实无法反转该矩阵.这很容易成为我遇到的最奇怪的GL错误.但是,为什么在着色器中反转矩阵是一个坏主意的某种解释将是值得赞赏的.EditAgain:在我的引擎中发送倒置矩阵导致了巨大的帧率提升.绝对做到了.
任意 4x4 矩阵求逆并不是一项快速且安全的任务
由于许多原因,例如GPU端的FPU精度较低以及求逆期间需要多次除法(这取决于计算方法),并且并非所有矩阵都有逆矩阵等(我认为这也是GL没有这样的实现的原因要么)...为了更好地了解这一点,请参阅了解 4x4 齐次变换矩阵并查找matrix_inv函数,计算实际上有多复杂(它使用行列式)。还有 GEM(高斯消除法),但由于其怪癖和需要对行进行排序而未使用......
如果矩阵在每帧渲染中都是静态的(通常是这种情况),那么在每个顶点/片段中一次又一次地在顶点/片段/几何着色器中计算它会浪费 GPU 功率(这就是速度提升的原因)。
有人可能会反对正交齐次矩阵求逆只是转置矩阵,但是 GL/GLSL 如何知道它处理这样的矩阵(检查也不是那么简单)无论如何,在这种情况下你可以使用transpose在 GLSL 中实现的并且应该速度要快(这只是元素的重新排序)