Opengl:Unexpected 尝试画线以可视化鼠标射线投射时的行为

Opengl:Unexpected behaviour when trying to draw a line to visualise mouse Ray cast

我正在尝试使用光线投射在我的应用程序中实现鼠标拾取。
我想做的是从字面上画出单击鼠标时从屏幕投射的线条。
这是我所做的:

float xNormalised = ((float)200/w.getWidth())*2 -1;
float yNormalised = -(((float)300/w.getHeight())*2 -1);

glm::vec4 nearP = glm::vec4(xNormalised,yNormalised,-1,1);
glm::vec4 farP = glm::vec4(xNormalised,yNormalised,1,1);

为简单起见,我硬编码了投射光线的鼠标坐标, 我将它们映射到规范化的设备坐标,然后我创建了两个代表两个点的向量:离屏幕最近的点和同一条线上最远的点。

worldNear = getInversedPoint(nearP,proj, view);
worldFar = getInversedPoint(farP,proj, view);

然后我在每个点上调用这个函数来基本上反转管道以获得它们在世界上的版本space,这是它的作用:

glm::vec4 getInversedPoint(glm::vec4 point,glm::mat4& proj,glm::mat4 view){

    //glm::mat4 inv = inverse(proj*view);
    point = point*inverse(proj);
    auto v = vec4(point.x/point.w,point.y/point.w,point.z/point.w,1);
    //auto v = vec4(point.x/point.w,point.y/point.w,point.z/point.w,point.w);
    point = v*inverse(view);
    return vec4(point.x,point.y,point.z,point.w);
}

在这之后我应该得到世界上的两个点数 space 如果我没记错的话, 所以我将这两个点放在缓冲区中并调用 gldraw 绘制连接它们的线。

我所期待的基本上是我放置的坐标中的一个红点,因为它是从点击点到它前面的点的直线...但我得到了一条奇怪的线或更多less 在屏幕中央,这不是我指定的位置..
我做错了什么?

您可以看到中间的红线,靠近横向三角形。
我的顶点着色器:

#version 330 core

layout(location = 1)in vec4 pos;
uniform mat4 projectMat;
uniform mat4 viewMat;

void main(){
    gl_Position = pos;
} 

我也尝试将点乘以两个矩阵,但变化很小。

您可以使用glm::unproject获取远近点:

glm::vec3 near = glm::unProject(glm::vec3(mouseX, winSize.y - mouseY, 0), // the screen-space coordinate
                                camera.view,
                                camera.projection,
                                glm::vec4(0, 0, winSize)); // your viewport

glm::vec3 far = glm::unProject(glm::vec3(mouseX, winSize.y - mouseY, 0), // the screen-space coordinate
                               camera.view,
                               camera.projection,
                               glm::vec4(0, 0, winSize)); // your viewport

你也可以通过读取framebuffer直接获取鼠标下的点:

/** read depth buffer and get the point under the cursor **/
        float depth;
        glReadPixels(mouseX, winSize.y - mouseY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
        if (depth < 1.0)
            point_on_plane = glm::unProject(glm::vec3(mouseX, winSize.y - mouseY, depth), camera.view,
                                            camera.projection,
                                            glm::vec4(0, 0, winSize));