【问题标题】:Kd tree for triangle meshes is too slow三角形网格的 Kd 树太慢
【发布时间】:2016-12-13 19:54:46
【问题描述】:

Kd 算法从创建 BSP 根节点开始,通过划分基元数组(三角形、球体等)来创建两个新数组(左右基元),用于创建其两个子树。

通过将给定的基元数组划分为两个数组来计算左右基元。通过取每个三角形的区间(投影到给定轴(x,y或z)上)的中点的中值来计算分割平面位置。

例如,具有 x 坐标的三角形:1、2、3 的中点为 1=(3-1)/2(沿 x 轴) 具有 x 坐标的三角形:2、3、8 的中点为 3=(8-2)/2(沿 x 轴) 具有 x 坐标的三角形:4、3、8 的中点为 2.5=(8-3)/2(沿 x 轴) 包含这三个三角形的原始数组由一个平面划分,通过 x=2.5(中值)平行于 yz 平面。生成的左图元数组包含三个三角形,生成的右图元数组包含三个三角形。

得到的两个带有左右基元的数组用于构造 Kd 节点的左右子树(基元只存储在叶节点处)。

对于左子树:

If (the left primitives are empty) then the left subtree points to NULL
else if (the number of left primitives is smaller than the minimal number || the depth == 1) then the left subtree is a leaf node
else the left subtree is another tree.

create the left subtree with the left primitives along the axis (++axis % 3) with --depth as depth and the same minimal number.

右子树类似。

实现的算法有效,但速度很慢,因为树的分区不是很好。对 5500 个三角形的兔子进行光线追踪时,1 个三角形的叶节点很多,而最后一个叶节点仍然包含 762 个三角形。

是否有更好的分区算法(因为我的只是一个 Kd 树的实现,用于将单点转换为表面),可以平衡树?

更新:我搜索了一种算法或启发式算法,可以根据切割点将区间数组 [t0,t1] 划分为两个区间数组。左侧数组包含切割点左侧的间隔和包含切割点的间隔。类似于正确的阵列。两个数组必须具有大致相同的间隔数,并且重复间隔的数量必须尽可能少。这个算法的复杂度可能不是 O(n^2)。

【问题讨论】:

  • 我对您问题中三角形的中点感到困惑。对于 x 坐标为 2,3,8 的三角形,为什么中点不是 2 + (8-2)/2 = 5? x 坐标为 1,2,3 的三角形应该有中点 1 + (3-1)/2 = 2 不是吗?这可能是具有 1 个三角形或 > 700 个三角形的非常不平衡的叶子的问题吗?
  • @PeteUK:你说得对:我没有在问题和代码中都包含偏移量。所以这可能是问题所在(完整的兔子模型以原点为中心,因此如果翻译它可能会更糟)。为了确定(但我们可以肯定),我将不再对此进行测试,因为它已经可以追溯到 2013 年(并且上述任何内容都没有出现在也可以追溯到 2013 年的最新版本中)。你终于可以回答这个问题了:)。

标签: raytracing bsp


【解决方案1】:

我建议您使用表面积启发式 (SAH) 来寻找最佳分割。

射线与子树相交的概率 - 与该子树边界框的表面积成正比。

但是,如果叶子子树包含很多三角形 - 这意味着我们必须遍历它们。

因此,SAH 的主要思想是最小化这两个方面:子树的表面积和其中的多边形数量。

让我们看一下小型 2D 示例:

此外,使用 SAH - 有助于确定 kd-tree 构建过程中的终止条件:

1) 在构建kd-tree的每一步,在子树分裂之前-你必须计算当前子树的SAH

SAH_initial = number_of_polygons * area_of_subtree

2) 在你必须找到当前子树的最优分割的 SAH 之后

SAH_optimal = min(S_left * N_left + S_right * N_right)

3) 你必须比较之后:

define some split_cost
...

if( SAH_optimal + split_cost < SAH_initial ) { 
   it would be optimal to split that subtree
} else {
   you don't have to split current subtree
}

这是另一个answer on Stackoverflow,其中包含对有关 SAH 的文章的引用。

【讨论】:

  • 更准确地说 - 表面积之间的比率受分割边界之间的比率影响。此外,在实践中,使用表面积的相对值更方便(它可以防止在计算乘积时浮点溢出:suarface_area * number_of_polygons)。
【解决方案2】:

中间点的计算看起来不正确。对于 x 坐标为 2,3,8 的三角形,中点应为 2 + (8-2)/2 = 5。 x 坐标为 1,2,3 的三角形应有中点 1 + (3-1)/2 = 2. 这可以解释不平衡的叶子。

【讨论】:

    猜你喜欢
    • 2013-07-13
    • 2011-05-11
    • 2019-01-28
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 2016-02-08
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多