我正在渲染一种旧的游戏格式,其中我有一个网格列表,组成了你所在的网格。我终于得到了PVS(从另一个区域可见的区域)工作,并且削减了很多网格我不需要渲染但不需要渲染。所以现在,我应该渲染的网格列表只包括我能看到的其他网格。但它并不完美。仍然有很多网格包括真正遥远的网格。
现在首先,我试图剔除不在我视野中的网格物体。我听说边界框是最好的方法。有没有人知道我怎么能这样做?我知道我需要最大点(x,y z)和最小点(x,y z),以便一个框包含所有的顶点。
然后,我是否检查并查看这些点中的任何一个是否在我的视锥中?这么简单吗?
谢谢!
答案 0 :(得分: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,然后在较小的列表上执行更准确的测试,并为截锥体和/或网格物体提供更准确的边界体积。 / p>