2

我正在尝试实现一种光线拾取算法,用于绘制和选择块(因此我需要相当高的准确性)。最初我采用了光线投射实现,但我觉得它不够准确(尽管问题可能出在我的相交测试上)。无论如何,我决定尝试使用深度缓冲区进行拾取,并将鼠标坐标转换为世界坐标。下面的实现:

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 来准确识别选择了哪个多边形?

4

1 回答 1

1

颜色是要走的路,深度缓冲区的精度取决于平面距离、FBO 纹理的分辨率,也取决于表面的法线或坡度。在标准阴影期间也会出现同样的精度问题。(使用颜色会更容易一些,因为通过深度交叉测试,一个对象有更多的“颜色”,深度值。如果一个对象有一种颜色,则更准确。)

另外,也许只有我一个人,但如果没有必要,我喜欢避免相当复杂的矩阵计算。可怜的 CPU 做其他事情就足够了。

对于双精度值,这可能会严重降低性能。我遇到过这种性能下降,我使用双精度而不是浮点数要慢 3 倍

我的帖子: GLSL 性能 - 函数返回值/类型和有关此的文章: https ://superuser.com/questions/386456/why-does-a-geforce-card-perform-4x-slower-in-double-precision比特斯拉卡

所以是的,你可以使用 64 位浮点数(双): http ://www.opengl.org/registry/specs...hader_fp64.txt和http://www.opengl.org/registry/specs.. .trib_64bit.txt,但你不应该。

总而言之,使用彩色多边形,我喜欢颜色 khmm...

编辑:关于双精度深度的更多信息:http ://www.opengl.org/discussion_boards/showthread.php/173450-Double-Precision ,这是一个很好的讨论

于 2013-12-03T20:32:46.890 回答