使用八叉树算法进行网格渲染

时间:2009-01-10 21:53:42

标签: c++ direct3d octree 3d-engine

我是SceneMax的创始人 - 自2005年以来的3D脚本语言。我想添加一个场景渲染,使用一个使用3d包构建的网格对象,如3ds max,并通过八叉树算法进行拆分,以优化性能。

你知道在哪里可以找到一个采用网格.X文件的算法,将其拆分为节点(八叉树)并知道如何渲染它吗?我想将它添加到我的引擎中。该引擎是开源的(如果您有兴趣,可以使用Google for SceneMax。)

2 个答案:

答案 0 :(得分:3)

有几种变体,但在构建八叉树时,有一种方法是:

  1. 从一个节点(即一个多维数据集)开始,包含整个场景或正在分区的对象。
  2. 对于场景/对象中的每个元素(例如,网格,聚合或您正在处理的任何粒度):
    1. 检查该元素是否完全适合节点。
    2. 如果是,请将节点细分为8个子节点,然后递归地为每个孩子执行第2步。
    3. 如果不是,则继续到下一个节点,直到没有节点为止。
    4. 将元素添加到可以包含它的最小节点。
  3. 基于某种启发式方法停止递归也很常见,例如节点的大小或节点内元素的数量是否小于某个阈值。

    有关构建八叉树的更多详细信息,请参阅this Flipcode tutorial

    一旦有了八叉树,就可以采用几种方法来渲染它。基本的想法是,如果你不能“看到”一个节点,那么你也看不到它的子节点,因此不需要渲染该节点(及其子节点)内的所有内容。

    Frustum剔除很容易实现,“你能看到吗?”使用视图投影的平截头体进行测试。 Gamedev.net has an article讨论截头剔除和其他一些方法。

    您还可以进一步实现截头剔除后的遮挡剔除,这将允许您跳过渲染由前面的节点覆盖的任何节点,使用z缓冲区来确定节点是否被隐藏。这涉及能够从最近到最远的遍历八叉树节点。 this Gamasutra article中讨论了这种技术。

答案 1 :(得分:0)

首先考虑您将不得不支持的网格文件类型非常重要。

实际上有3种不同的对象。  1.开阔的自然地形。这非常适合四叉树,因为八叉树带来了不必要的复杂性。没有理由引入第三维,如果它不会给你带来太多的性能提升。  2.打开有许多高大物体的地形。这非常适合八叉树,因为八叉树允许你从渲染中移除垂直轴上的东西,而像这样的场景有很多。老实说,我不能说出任何符合我头脑的东西。  3.封闭空间或角色模型/静态网格物体。这非常适合BSP树。 BSP树允许完全在屏幕上的对象或封闭空间仅根据需要渲染多个多边形。

我建议添加1和3,假设1甚至是您需要支持的模型类型。 #3对于第一人称射击游戏或角色模型来说非常标准,并且增加对它的支持可能会给你最好的效果。整体想法是尽可能多地从渲染中移除几何体,因此95%的户外地形玩家游戏世界的四元树是完美的。八叉树有用,但比你想象的要少。

这些算法中的每一个都相对容易编写。例如,我在很多年前的3小时内写了一个八叉树。通常这些是在加载时处理的,几何图形被添加到每个正方形(如果是四边形/八叉树)或树(如果是BSP),然后渲染跟随。通过快速谷歌搜索有很多很棒的文章,我将留给你研究。快速说明的是,BSP树还具有处理碰撞检测的能力,是角色模型和静态网格物体的理想候选者。因此,这是一种算法,我建议您花点时间,以确保它足够灵活,可以多次使用。