1

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

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

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

谢谢!

4

1 回答 1

2

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 的网格列表,然后对该较小的列表执行更准确的测试,并为平截头体和/或网格提供更准确的边界体积。

于 2011-06-09T04:02:30.690 回答