【问题标题】:Mesh rendering using Octree algorithm使用八叉树算法进行网格渲染
【发布时间】:2009-01-10 21:53:41
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

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

    1. 从一个包含整个场景或被分割对象的节点(即立方体)开始。
    2. 对于场景/对象中的每个元素(例如网格、多边形或您正在处理的任何粒度):
      1. 检查该元素是否完全适合节点。
      2. 如果是,则将节点细分为八个子节点,然后对每个子节点递归执行第 2 步。
      3. 如果没有,则继续下一个节点,直到没有节点为止。
      4. 将元素添加到可以包含它的最小节点。

    根据一些启发式停止递归也很常见,例如节点的大小或节点内的元素数量是否小于某个阈值。

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

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

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

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

    【讨论】:

    • 我认为棘手的部分是两个立方体之间的边界。如果一个多边形部分位于两个或多个立方体中,你会怎么做?您可以将多边形添加到每个相关的立方体中,根据测量值(如面积)确定多边形属于一个立方体,也可以拆分多边形。
    • gamedev.net 链接已失效
    【解决方案2】:

    首先考虑您必须支持的网格文件类型很重要。

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多