【问题标题】:Bounding box frustum rendering - Distance rendering - OpenGL边界框平截头体渲染 - 距离渲染 - OpenGL
【发布时间】:2011-09-11 08:47:47
【问题描述】:

我正在渲染一种旧的游戏格式,其中我有一个构成你所在的网格的列表。我终于让 PVS(从另一个区域可见的区域)工作了,并且我剪掉了很多网格不需要渲染,但不需要太多。所以现在,我应该渲染的网格列表只包括我可以看到的其他网格。但它并不完美。仍然有大量的网格,包括超出剪辑的非常远的网格。

现在首先,我试图剔除不在我的视锥体中的网格。我听说边界框是执行此操作的最佳方法。有谁知道我该怎么做?我知道我需要最大点 (x, y z) 和最小点 (x, y z) 以便一个框包含所有顶点。

那么,我是否要检查这些点中的任何一个是否在我的视锥中?就这么简单吗?

谢谢!

【问题讨论】:

    标签: c++ opengl bounding-box frustum


    【解决方案1】:

    AABB 或 Axis Aligned Bounding Box 是一个非常简单且快速的对象,用于测试两个 3D 区域的交叉/包含。

    按照您的建议,您正在计算要比较的两个区域的最小值和最大值 x,y,z,例如,描述截头体的区域和描述网格的区域。它是轴对齐的,因为随后的立方体具有与坐标系的每个轴平行的边缘。显然,这可能有点不准确(交叉/包含的误报,但绝不是误报),因此一旦您使用 AABB 测试过滤列表,您可能会考虑对剩余的网格执行更准确的测试。

    您按如下方式测试交叉/包含:

    F = AABB 截锥体

    M = AABB 网格

    bool is_mesh_in_frustum(const AABB& F, const AABB& M)
    {
        if( F.min.x > M.max.x || M.min.x > F.max.x || F.min.y > M.max.y || M.min.y > F.max.y || F.min.z > M.max.z || M.min.z > F.max.z )
        {
            return false;
        }
        return true;
    }
    

    您还可以查找用于包围球、定向包围盒 (OBB) 和其他类型包围体的算法。根据您要渲染的网格数量,您可能需要也可能不需要更准确的方法。

    首先要创建 AABB,您可以简单地遍历网格的顶点并记录您遇到的最小/最大 x 和 y 和 z 值。

    还要考虑,如果网格不变形,那么网格坐标空间中的边界框将是静态的,因此您可以在获得顶点数据后立即计算所有网格的 AABB。

    然后,您只需确保在每次渲染传递测试之前将预先计算的 AABB 最小和最大顶点转换到截锥坐标空间。

    编辑(供评论):

    AABB 可能会提供误报,因为它充其量是您要界定的区域的确切形状,但通常比您要界定的区域大。

    考虑一个球体,如果你使用AABB,就像把一个篮球放进一个盒子里,你在盒子的角落里有所有这些球无法到达的缝隙。

    或者在截锥体向内朝向相机倾斜的情况下,它的 AABB 将简单地沿着轴朝向相机直线继续,有效地界定了一个比相机可以看到的区域更大的区域。

    这是不准确的来源,但它绝不会导致您剔除稍微位于截锥体内的对象,因此最坏的情况下,您仍将绘制一些靠近相机但仍在截锥体之外的网格。

    您可以通过首先进行 AABB 测试来纠正此问题,并生成一个较小的返回 true 的网格列表,然后对该较小的列表执行更准确的测试,并为平截头体和/或网格提供更准确的边界体积。

    【讨论】:

    • 谢谢!我只是好奇,当它不是一个盒子,而是一个金字塔形状时,截锥体中怎么会有一个 AABB。
    猜你喜欢
    • 2018-06-11
    • 2011-04-20
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    相关资源
    最近更新 更多