我正在尝试实现一种光线拾取算法,用于绘制和选择块(因此我需要相当高的准确性)。最初我采用了光线投射实现,但我觉得它不够准确(尽管问题可能出在我的相交测试上)。无论如何,我决定尝试使用深度缓冲区进行拾取,并将鼠标坐标转换为世界坐标。下面的实现:
glm::vec3 Renderer::getMouseLocation(glm::vec2 coordinates) {
float depth = deferredFBO->getDepth(coordinates);
// Calculate the width and height of the deferredFBO
float viewPortWidth = deferredArea.z - deferredArea.x;
float viewPortHeight = deferredArea.w - deferredArea.y;
// Calculate homogenous coordinates for mouse x and y
float windowX = (2.0f * coordinates.x) / viewPortWidth - 1.0f;
float windowY = 1.0f - (2.0f * coordinates.y) / viewPortHeight;
// cameraToClip = projection matrix
glm::vec4 cameraCoordinates = glm::inverse(cameraToClipMatrix)
* glm::vec4(windowX, windowY, depth, 1.0f);
// Normalize
cameraCoordinates /= cameraCoordinates.w;
glm::vec4 worldCoordinates = glm::inverse(worldToCameraMatrix)
* cameraCoordinates;
return glm::vec3(worldCoordinates);
}
问题是这些值很容易达到 ±3 个单位(块为 1 个单位宽),只有在非常接近近剪裁平面时才足够准确。
不准确性是否源于使用单精度浮点数,或者可能是我计算中的某个步骤?如果我使用双精度值会有帮助吗?OpenGL 甚至支持深度缓冲区吗?
最后,如果这种方法不起作用,我是否最好使用颜色 ID 来准确识别选择了哪个多边形?