使用GLM的UnProject函数

8
我不确定如何使用GLM提供的反投影方法
具体来说,视口是以什么格式传递的?为什么该函数不需要视图矩阵,只需要投影和世界矩阵呢?

这里提供了一个Rust的解决方案,欢迎从谷歌跳转过来的任何人使用。 - vallentin
2个回答

23
这里需要一点历史知识。GLM的反投影实际上是gluUnProject函数的直接替代品,该函数使用已弃用的OpenGL固定功能渲染。在此模式下,模型矩阵和视图矩阵实际上合并为“ModelView”矩阵。显然,GLM的作者在命名时省略了“view”部分,更加混淆了事情,但归根结底是传递类似于view*model的内容。
现在来看实际使用:
  • win是一个向量,包含三个在窗口坐标系中有意义的分量。这些分量是视口中的坐标'x,y',通常通过读取深度缓冲区在(x,y)处检索到的“z”坐标。
  • 如果你考虑使用这个函数,模型、视图和投影矩阵应该很清楚了。但是一个好的(opengl-specific)refresher可能会有用。
  • 视口被定义为glViewport中的(x,y,w,h)。X和Y指定视口的左下角(通常为0,0)。宽度和高度(w,h)。请注意,在许多其他系统中,x,y指定的是左上角,您必须转换您的y坐标,这在我下面链接的NeHe代码中显示。

应用时,你只需将提供的窗口坐标转换回对象坐标,这基本上是你的渲染代码通常所做的反向操作。

可以在NeHe文章中找到关于原始gluUnProject的半靠谱解释。但当然,那是针对OpenGL特定的,而glm可以用于其他情境。


3
除了视口不是一个矩阵外,它是由四个浮点数表示的。因此我对这些参数的顺序等信息感到困惑。 - Puppy

2
视口由四个浮点数传入:视口的x和y窗口坐标,接着是它的宽度和高度。这与例如glGetFloatv(GL_VIEWPORT, ...)使用的顺序相同。因此,在大多数情况下,前两个值应该为0。
正如KillianDS已经指出的那样,在实际中,model参数实际上是一个模型视图矩阵,请参见在gtx_simd_mat4.cpp中使用unProject()的示例,函数test_compute_gtx()
    glm::mat4 E = glm::translate(D, glm::vec3(1.4f, 1.2f, 1.1f));
    glm::mat4 F = glm::perspective(i, 1.5f, 0.1f, 1000.f);
    glm::mat4 G = glm::inverse(F * E);
    glm::vec3 H = glm::unProject(glm::vec3(i), G, F, E[3]);

正如您所看到的,作为第二个参数传递的矩阵基本上是平移和透视变换的乘积。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接