无法用鼠标选择在帧缓冲区中渲染的四边形
Unable to mouse pick a quad rendered in a framebuffer
奋力鼠标挑一个point/quad。我相信我要么在错误的 space 中使用坐标,要么可能没有考虑帧缓冲区的 position/size(它是主 window 的子 window)。
尝试转换为各种不同的坐标 spaces 并反转模型矩阵。当前正在世界 space 中投射一条射线(希望正确)并尝试将其与点的(四边形)位置进行比较。该点在本地 space 中指定,但实体在原点 (0f, 0f, 0f) 处呈现,因此我认为它在世界 space?[=15= 中应该没有任何不同]
获取世界中的鼠标射线space:
private fun calculateRay(): Vector3f {
val mousePosition = Mouse.getCursorPosition()
val ndc = toDevice(mousePosition)
val clip = Vector4f(ndc.x, ndc.y, -1f, 1f)
val eye = toEye(clip)
return toWorld(eye)
}
private fun toDevice(mousePosition: Vector2f): Vector2f {
mousePosition.x -= fbo.x // Correct thing to do?
mousePosition.y -= fbo.y
val x = (2f * mousePosition.x) / fboSize.x - 1
val y = (2f * mousePosition.y) / fboSize.y - 1
return Vector2f(x, y)
}
private fun toEye(clip: Vector4f): Vector4f {
val invertedProjection = Matrix4f(projectionMatrix).invert()
val eye = invertedProjection.transform(clip)
return Vector4f(eye.x, eye.y, -1f, 0f)
}
private fun toWorld(eye: Vector4f): Vector3f {
val viewMatrix = Maths.createViewMatrix(camera)
val invertedView = Matrix4f(viewMatrix).invert()
val world = invertedView.transform(eye)
return Vector3f(world.x, world.y, world.z).normalize()
}
悬停在点(11.25, -0.75)上时,光线坐标为(0.32847548, 0.05527423)。我尝试标准化点的位置,但仍然不匹配。
感觉我在missing/overlooking什么东西,或者只是错误地操纵了坐标系。任何见解将不胜感激,谢谢。
编辑更多信息:
四边形的顶点是:
(-0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f)
正在将矩阵加载到着色器:
private fun loadMatrices(position: Vector3f, rotation: Float, scale: Float, viewMatrix: Matrix4f, currentRay: Vector3f) {
val modelMatrix = Matrix4f()
modelMatrix.translate(position)
modelMatrix.m00(viewMatrix.m00())
modelMatrix.m01(viewMatrix.m10())
modelMatrix.m02(viewMatrix.m20())
modelMatrix.m10(viewMatrix.m01())
modelMatrix.m11(viewMatrix.m11())
modelMatrix.m12(viewMatrix.m21())
modelMatrix.m20(viewMatrix.m02())
modelMatrix.m21(viewMatrix.m12())
modelMatrix.m22(viewMatrix.m22())
modelMatrix.rotate(Math.toRadians(rotation.toDouble()).toFloat(), Vector3f(0f, 0f, 1f))
modelMatrix.scale(scale)
shader.loadModelViewMatrix(viewMatrix.mul(modelMatrix))
shader.loadProjectionMatrix(projectionMatrix)
}
在顶点着色器中计算 gl_Position:
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 0.0, 1.0);
编辑 2:根据 Rabbid 的评论 material 阅读了更多内容后更改了我的代码。不确定我是否需要在视口大小中除以 2(我有视网膜 MacBook 显示器)。
mousePosition.sub(fboPosition)
val w = (fboSize.x / 2).toInt()
val h = (fboSize.y / 2).toInt()
val y = h - mousePosition.y
val viewMatrix = Maths.createViewMatrix(camera)
val origin = Vector3f()
val dir = Vector3f()
Matrix4f(projectionMatrix).mul(viewMatrix)
.unprojectRay(mousePosition.x, y, intArrayOf(0, 0, w, h), origin, dir)
window 空间的左上原点是 (0,0)。因此,如果你得到 (0, 0),如果鼠标位于 window 的左上角,你必须跳过:
mousePosition.x -= fbo.x // Correct thing to do?
mousePosition.y -= fbo.y
由于framebuffer的左下角是(0,0),y坐标需要翻转:
val y = 1 - (2f * mousePosition.y) / fboSize.y
当Cartesian coordinate is transformed by a (inverse) projection matrix, then the result is a Homogeneous coordinates. You've to do a Perspective divide时,获取视图中的笛卡尔坐标space:
val eye = invertedProjection.transform(clip)
return Vector3f(eye.x/eye.w, eye.y/eye.w, eye.z/eye.w)
奋力鼠标挑一个point/quad。我相信我要么在错误的 space 中使用坐标,要么可能没有考虑帧缓冲区的 position/size(它是主 window 的子 window)。
尝试转换为各种不同的坐标 spaces 并反转模型矩阵。当前正在世界 space 中投射一条射线(希望正确)并尝试将其与点的(四边形)位置进行比较。该点在本地 space 中指定,但实体在原点 (0f, 0f, 0f) 处呈现,因此我认为它在世界 space?[=15= 中应该没有任何不同]
获取世界中的鼠标射线space:
private fun calculateRay(): Vector3f {
val mousePosition = Mouse.getCursorPosition()
val ndc = toDevice(mousePosition)
val clip = Vector4f(ndc.x, ndc.y, -1f, 1f)
val eye = toEye(clip)
return toWorld(eye)
}
private fun toDevice(mousePosition: Vector2f): Vector2f {
mousePosition.x -= fbo.x // Correct thing to do?
mousePosition.y -= fbo.y
val x = (2f * mousePosition.x) / fboSize.x - 1
val y = (2f * mousePosition.y) / fboSize.y - 1
return Vector2f(x, y)
}
private fun toEye(clip: Vector4f): Vector4f {
val invertedProjection = Matrix4f(projectionMatrix).invert()
val eye = invertedProjection.transform(clip)
return Vector4f(eye.x, eye.y, -1f, 0f)
}
private fun toWorld(eye: Vector4f): Vector3f {
val viewMatrix = Maths.createViewMatrix(camera)
val invertedView = Matrix4f(viewMatrix).invert()
val world = invertedView.transform(eye)
return Vector3f(world.x, world.y, world.z).normalize()
}
悬停在点(11.25, -0.75)上时,光线坐标为(0.32847548, 0.05527423)。我尝试标准化点的位置,但仍然不匹配。
感觉我在missing/overlooking什么东西,或者只是错误地操纵了坐标系。任何见解将不胜感激,谢谢。
编辑更多信息:
四边形的顶点是:
(-0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f)
正在将矩阵加载到着色器:
private fun loadMatrices(position: Vector3f, rotation: Float, scale: Float, viewMatrix: Matrix4f, currentRay: Vector3f) {
val modelMatrix = Matrix4f()
modelMatrix.translate(position)
modelMatrix.m00(viewMatrix.m00())
modelMatrix.m01(viewMatrix.m10())
modelMatrix.m02(viewMatrix.m20())
modelMatrix.m10(viewMatrix.m01())
modelMatrix.m11(viewMatrix.m11())
modelMatrix.m12(viewMatrix.m21())
modelMatrix.m20(viewMatrix.m02())
modelMatrix.m21(viewMatrix.m12())
modelMatrix.m22(viewMatrix.m22())
modelMatrix.rotate(Math.toRadians(rotation.toDouble()).toFloat(), Vector3f(0f, 0f, 1f))
modelMatrix.scale(scale)
shader.loadModelViewMatrix(viewMatrix.mul(modelMatrix))
shader.loadProjectionMatrix(projectionMatrix)
}
在顶点着色器中计算 gl_Position:
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 0.0, 1.0);
编辑 2:根据 Rabbid 的评论 material 阅读了更多内容后更改了我的代码。不确定我是否需要在视口大小中除以 2(我有视网膜 MacBook 显示器)。
mousePosition.sub(fboPosition)
val w = (fboSize.x / 2).toInt()
val h = (fboSize.y / 2).toInt()
val y = h - mousePosition.y
val viewMatrix = Maths.createViewMatrix(camera)
val origin = Vector3f()
val dir = Vector3f()
Matrix4f(projectionMatrix).mul(viewMatrix)
.unprojectRay(mousePosition.x, y, intArrayOf(0, 0, w, h), origin, dir)
window 空间的左上原点是 (0,0)。因此,如果你得到 (0, 0),如果鼠标位于 window 的左上角,你必须跳过:
mousePosition.x -= fbo.x // Correct thing to do?
mousePosition.y -= fbo.y
由于framebuffer的左下角是(0,0),y坐标需要翻转:
val y = 1 - (2f * mousePosition.y) / fboSize.y
当Cartesian coordinate is transformed by a (inverse) projection matrix, then the result is a Homogeneous coordinates. You've to do a Perspective divide时,获取视图中的笛卡尔坐标space:
val eye = invertedProjection.transform(clip)
return Vector3f(eye.x/eye.w, eye.y/eye.w, eye.z/eye.w)