C++ OpenGL是否将屏幕定位在相机前面?

C++ OpenGL是否将屏幕定位在相机前面?,c++,opengl,glm-math,C++,Opengl,Glm Math,我正在尝试将鼠标单击转换为全局位置。尽管世界空间是3d的,但我目前正在尝试查找z=0时单击的x和y坐标 我已经编写了一些代码来进行转换,它几乎是正确的。但似乎有一个误差随着距离(0,0)的增加而增大。它似乎增长太快,不可能是一个舍入误差,所以我认为屏幕并没有精确地设置为相机的位置 对于这个测试,我主要关注x坐标 变数 screenWidth = 512; screenHeight = 512; cameraPos = glm::vec3(0.0f, 0.0f, 4.0f); 转换逻辑

我正在尝试将鼠标单击转换为全局位置。尽管世界空间是3d的,但我目前正在尝试查找z=0时单击的x和y坐标

我已经编写了一些代码来进行转换,它几乎是正确的。但似乎有一个误差随着距离(0,0)的增加而增大。它似乎增长太快,不可能是一个舍入误差,所以我认为屏幕并没有精确地设置为相机的位置

对于这个测试,我主要关注x坐标

变数

screenWidth = 512;
screenHeight = 512;
cameraPos = glm::vec3(0.0f, 0.0f, 4.0f);
转换逻辑

    std::cout << "mouse float x: " << inMouseX << ", mouse float y: " << inMouseY << std::endl;


    float mouseX = (inMouseX / ((float)screenWidth * 0.5f)) - 1.0f;
    float mouseY = (inMouseY / ((float)screenHeight * 0.5f)) - 1.0f;

    std::cout << "mouse adjusted screen width x: " << (float)screenWidth * 0.5f << ", mouse adjusted screen height y: " << (float)screenHeight * 0.5f << std::endl;
    std::cout << "mouse 2nd adjusted x: " << ((inMouseX / (float)screenWidth * 0.5f)) << ", mouse 2nd adjusted y: " << ((inMouseY / (float)screenHeight * 0.5f)) << std::endl;

    std::cout << "mouse converted x: " << mouseX << ", mouse converted y: " << mouseY << std::endl;

    glm::mat4 invVP = glm::inverse(*projection * *view);

    glm::vec4 mouseClickVector = invVP * glm::vec4(mouseX, -mouseY, 1.0f, 1.0f);

    glm::vec3 norm = glm::normalize(glm::vec3(mouseClickVector));

    float t = (0 - (*cameraPos)[2]) / norm[2];

    glm::vec3 trueWorldPos = *cameraPos + (norm * t);

    return trueWorldPos;

我预计会有一些波动,因为我使用鼠标不精确,可能还有一些小的舍入问题,但它比我预期的要大得多。

假设视图矩阵有一些标准约定,这没有意义:

通常,视图矩阵包含摄影机的方向和位置。您似乎将
mouseClickVector
视为一个方向。但是如果你的相机不在世界空间中心,这种标准化会产生完全虚假的结果

要获得未投影点的正确世界空间位置,不能再忽略w组件:

glm::vec3 posWorld = (1.0f / mouseClickVector.w) * glm::vec3(mouseClickVector)

这只会在后平面上产生未投影的点(将NDC z设置为1.0)。您仍然需要计算从摄影机位置到该点的视图光线,以便计算与某个世界空间平面的交点。

非常感谢您的关注!,我对这个问题的数学计算有点不知所措,但我想我可以澄清一些问题。我的目标是试图撤销我为渲染而做的数学运算。我试图在3d空间中找到一个与鼠标点击相关的点。然后我试图找到相机和鼠标点击点之间的距离z=0。最后,找到z=0处的位置。使用类似于
float t=(0-(*cameraPos)[2])/posWorld[2];glm::vec3 worldPos=*cameraPos+(posWorld*t2),我得到了与标准化结果相同的结果;稍有错误。不清楚您在这里到底在做什么,也不清楚世界空间中的
z=0
平面有什么相关性。但是,我写道,您需要通过获得
worldPos
cameraPos
的差值来计算视图光线。你只是把
worldPos
当作一个方向来使用,这是没有意义的。我误解了,你回答了我的问题。我设法使它工作起来。我是堆栈溢出的新手,正在编辑我的问题以澄清我的误解,以及您的回答和评论如何使我达到正确的程序?
glm::vec4 mouseClickVector = invVP * glm::vec4(mouseX, -mouseY, 1.0f, 1.0f);

glm::vec3 norm = glm::normalize(glm::vec3(mouseClickVector));
glm::vec3 posWorld = (1.0f / mouseClickVector.w) * glm::vec3(mouseClickVector)