未投影的鼠标坐标在 0-1 之间

UnProjected mouse coordinates are between 0-1

我正在尝试从我的鼠标位置创建一个 3D 射线 space,显然为了做到这一点,我需要 "UnProject()" 它。

这样做会为每个轴提供一个介于 0 和 1 之间的值。

不可能是正确的 从视口绘制 "Ray" 或一条线,可以吗?所有这一切,基本上是我的鼠标占视口大小的百分比。

如果这确实是对的,那么我不明白以下内容:

如果这实际上是错误的,那么是什么导致了这样的错误? 我尝试取消投影我自己对象的顶点,但这些顶点不受 0-1 的限制。 我不知道我在渲染时处理 "projections" 的方式是否与 gluUnproject 兼容。我一直按照这些教程显示的方式进行操作(接近底部):http://qt-project.org/wiki/Developer-Guides#28810c65dd0f273a567b83a48839d275

这是我尝试获取鼠标坐标的方法:

GLdouble modelViewMatrix[16];
GLdouble projectionMatrix[16];
GLint viewport[4];
GLfloat winX, winY, winZ;
glGetDoublev(GL_MODELVIEW_MATRIX, modelViewMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);
glGetIntegerv(GL_VIEWPORT, viewport);

winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels( winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

GLdouble nearPlaneLocation[3];
gluUnProject(winX, winY, 0, modelViewMatrix, projectionMatrix,
             viewport, &nearPlaneLocation[0], &nearPlaneLocation[1],
        &nearPlaneLocation[2]);

GLdouble farPlaneLocation[3];
gluUnProject(winX, winY, 1, modelViewMatrix, projectionMatrix,
             viewport, &farPlaneLocation[0], &farPlaneLocation[1],
        &farPlaneLocation[2]);

QVector3D nearP = QVector3D(nearPlaneLocation[0], nearPlaneLocation[1],
        nearPlaneLocation[2]);
QVector3D farP = QVector3D(farPlaneLocation[0], farPlaneLocation[1],
        farPlaneLocation[2]);

也许我的实际预测不对?

void oglWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    QMatrix4x4 mMatrix;
    QMatrix4x4 vMatrix;

    QMatrix4x4 cameraTransformation;
    cameraTransformation.rotate(alpha, 0, 1, 0);
    cameraTransformation.rotate(beta, 1, 0, 0);

    QVector3D cameraPosition = cameraTransformation * QVector3D(camX, camY, distance);
    QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);
    vMatrix.lookAt(cameraPosition, QVector3D(camX, camY, 0), cameraUpDirection);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(cameraPosition.x(), cameraPosition.y(), cameraPosition.z(), camX, camY, 0, cameraUpDirection.x(), cameraUpDirection.y(), cameraUpDirection.z());
    shaderProgram.bind();
    shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
    shaderProgram.setUniformValue("texture", 0);


    for (int x = 0; x < tileCount; x++)
    {
        shaderProgram.setAttributeArray("vertex", tiles[x]->vertices.constData());
        shaderProgram.enableAttributeArray("vertex");
        shaderProgram.setAttributeArray("textureCoordinate", textureCoordinates.constData());
        shaderProgram.enableAttributeArray("textureCoordinate");

        //Triangle Drawing
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tiles[x]->image.width(), tiles[x]->image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tiles[x]->image.bits());
        glDrawArrays(GL_TRIANGLES, 0, tiles[x]->vertices.size());
    }    

    shaderProgram.release();

}

其中,pMatrix 是一个 4x4 矩阵,在调整大小事件期间进行控制,例如:

 pMatrix.setToIdentity();
 pMatrix.perspective(fov, (float) width / (float) height, 0.001, 10000);
 glViewport(0, 0, width, height);

我的顶点着色器是这样设置的:

uniform mat4 mvpMatrix;

in vec4 vertex;
in vec2 textureCoordinate;

out vec2 varyingTextureCoordinate;

void main(void)
{
    varyingTextureCoordinate = textureCoordinate;
    gl_Position = mvpMatrix * vertex;
}

glReadPixels 采用整数(x 和 y),而您似乎出于某种原因在 gluUnProject 中没有使用 winZ。

这样试试:

gluUnProject(winX, winY, winZ, glView, glProjection, viewport, &posX, &posY, &posZ);

此外,如果您希望光线在遇到深度缓冲区中的某物时停止,则不要在渲染后清除深度缓冲区。如果你执行 glClear(GL_DEPTH_BUFFER_BIT) 那么光线应该到达你在投影矩阵中设置的远剪辑。

我也不知道为什么你需要多次调用它。最后三个浮点数将是目标向量,您可以只使用您的相机位置作为光线的来源(取决于您在做什么)。

我的部分问题是描述不当。我不小心留下了疯狂测试的残留代码,导致一些“读取像素”函数和相关的废话,这对解决问题没有用。

我的其他问题是由于矩阵的数据类型不一致,并且试图从 OpenGL 中提取矩阵,而 OpenGL 一开始就没有存储它们。

问题已解决:

  • Using GLM to hold all my matrices
  • 自己进行计算(逆视图矩阵*逆模型矩阵*逆投影矩阵)*持有NDC转换屏幕的向量space坐标(-1到1的范围:x或y除以宽度或高度, * 2 - 1), 它的远平面或近平面的 z 也为 -1 或 1,w 为 1.
  • 将结果除以向量的第四个点。

我仍然不知道为什么 unprojecting 对我不起作用,因为我用 GLU 和 GLM 的 unproject 函数得到了错误的结果,但是手动操作对我有用。

由于我的问题持续了相当长的时间,并提出了几个问题,我要感谢一路上帮助过我的几个人: