将 2d 屏幕位置投影到 3d 世界空间中

Posted

技术标签:

【中文标题】将 2d 屏幕位置投影到 3d 世界空间中【英文标题】:Unprojecting 2d screen position into 3d world space 【发布时间】:2012-01-08 14:45:42 【问题描述】:

我正在使用 glm 数学库来解决以下问题:将 2d 屏幕位置转换为 3d 世界空间。

为了追查问题,我将代码简化为以下内容:

    float screenW = 800.0f;
    float screenH = 600.0f;
    glm::vec4 viewport = glm::vec4(0.0f, 0.0f, screenW, screenH);
    glm::mat4 tmpView(1.0f);
    glm::mat4 tmpProj = glm::perspective( 90.0f, screenW/screenH, 0.1f, 100000.0f);
    glm::vec3 screenPos = glm::vec3(0.0f, 0.0f, 1.0f);
    glm::vec3 worldPos = glm::unProject(screenPos, tmpView, tmpProj, viewport);

现在使用 glm::unProject 在这种情况下,我希望 worldPos 为 (0, 0, 1)。但是它以 (127100.12, -95325.094, -95325.094) 的形式出现。

我是否误解了 glm::unProject 应该做什么?我已经跟踪了这个函数,它似乎工作正常。

【问题讨论】:

嗨。我对 glm::unProject 也有一些问题。我已经尝试过你的测试代码(复制粘贴它),对我来说 worldPos 是(-215677、-161758、-99864.4)知道为什么吗??? 【参考方案1】:

screenPos 中的 Z 分量对应于深度缓冲区中的值。所以 0.0f 是近裁剪面,1.0f 是远裁剪面。

如果你想找到距离屏幕一个单位的世界位置,你可以重新缩放向量:

worldPos = worldPos / (worldPos.z * -1.f);

还要注意,screenPos 的 0,0 表示屏幕的左下角,而在 worldPos 中,0,0 是屏幕的中心。所以 0,0,1 应该给你 -1.3333,-1,-1,而 400,300,1 应该给你 0,0,-1。

【讨论】:

以上是关于将 2d 屏幕位置投影到 3d 世界空间中的主要内容,如果未能解决你的问题,请参考以下文章

世界空间逆投影透视

OpenGL - 在 3D 世界的屏幕上固定位置打印 2D 文本

转载3D/2D中的D3DXMatrixPerspectiveFovLH和D3DXMatrixOrthoLH投影函数详解

4D转3D透视投影

如何在opengl中计算给定3D点及其2D屏幕位置的投影/模型视图矩阵

当摄像机旋转时,2d屏幕速度到3d世界速度