边界框截头体渲染-距离渲染-OpenGL

Bounding box frustum rendering - Distance rendering - OpenGL

本文关键字:距离 -OpenGL 边界      更新时间:2023-10-16

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

现在,首先,我尝试剔除不在我的视锥中的网格。我听说边界框是最好的方法。有人知道我该怎么做吗?我知道我需要最大点(x,yz)和最小点(x,y z),这样一个盒子就包含了所有的垂直面。

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

谢谢!

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