最有效的网格级最佳遮挡剔除算法?

时间:2008-11-25 15:01:34

标签: algorithm search graphics 3d

我是捣蛋的新手。乍一看,似乎大多数遮挡剔除算法都是对象级别的,而不是检查单个网格,这对于游戏渲染来说是实用的。

我正在寻找的是一种算法,它可以高精度地剔除单个对象中为给定视点遮挡的所有网格。它需要至少 O(n log n),一个天真的网格对比( O(n ^ 2))太慢。

我注意到Blender GUI可以实时识别遮挡的网格物体,即使您使用10,000+网格的大型物体也是如此。那里使用什么算法,祈祷告诉?

5 个答案:

答案 0 :(得分:3)

Blender基于Bullet物理库中的动态AABB树加速结构执行视锥体剔除和遮挡剔除。封堵器和对象由其边界体积(轴对齐边界框)表示。

在给定相机平截头体的情况下,查看视锥体剔除只是遍历AABB树。

遮挡剔除基于遮挡缓冲区,这是一种使用非常简单的软件渲染器初始化的深度缓冲区:使用动态AABB树加速结构的基本光线跟踪器。您可以选择遮挡缓冲区的分辨率来交换准确性与效率。

另见文档http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.49/Game_Engine#Performance

来自Blender源代码树的Blender实现: blender \ source \ gameengine \ Physics \ Bullet \ CcdPhysicsEnvironment.cpp方法 bool CcdPhysicsEnvironment :: cullingTest(PHY_CullingCallback回调,void * userData,PHY__Vector4 * planes,int nplanes,int occlusionRes)

并且Bullet Physics SDK在Bullet / Extras / CDTestFramework中有一些C ++示例代码。

答案 1 :(得分:1)

您是否查看了Octrees等内容?

答案 2 :(得分:1)

没有在网格级别进行剔除的原因是网格是一个非常愚蠢的渲染器级别对象,而游戏对象是在场景级别,所有剔除都发生在这里。没有采用网格级别剔除决策,如果需要渲染其对象,它们只是批处理具有相似着色器状态的基元的方法。

如果确实需要在网格级别进行剔除,则可能需要为每个网格创建一个对象,然后创建包含网格对象的组对象。请注意,实际上您可能会失去性能,因为在网格级别进行剔除通常是不值得的;它可能会破坏数据传输到硬件的流量。

答案 3 :(得分:0)

通常你要做的第一件事就是看看网格是否有可能互相遮挡。通常使用简单的边界基元(边界框或边界球)。如果我没记错的话,Octrees会对此有所帮助。

答案 4 :(得分:0)

我尝试了天真的方法,这对我的应用来说实际上足够快。

对于网格中的每个三角形,检查是否被网格中的任何其他三角形遮挡,因此 O(n2)。 (我只检查每个三角形上的中心点是否被遮挡,得到了高精度的结果,但如果准确性很重要,你至少应检查三角形拐角顶点)。

在奔腾4机器(c ++)上, ~100,000个三角形的二进制STL对象需要大约1分钟才能完成

通过首先对三角形进行排序,例如按区域大小或距离视点的距离(更可能遮挡,因此可以跳过更多检查),可以优化算法,最高可达~40%。

下一个优化步骤是将三角形放在八叉树中,这将大大减少遮挡检查的次数。