三角形的表面区域启发式(SAH)kd树 - 扁平单元

时间:2016-07-28 13:14:39

标签: algorithm 3d raytracing kdtree

我根据Wald和Havran的论文On building fast kd-Trees for Ray Tracing, and on doing that in O(N log N)实现了一个SAH kd-tree。注意我最后没有完成拼接和合并建议,以加快树的构建,只是SAH部分。

我正在使用轴对齐的立方体测试算法,其中每个面被分成两个三角形,所以我总共有N = 12个三角形。左下角的顶点(即最靠近轴的顶点)实际上位于原点。

cube of 5 units with each face split into 2 triangles

Face    Triangle
----------------
Front:  0, 1
Left:   6, 7
Right:  2, 3
Top:    4, 5
Bottom: 10, 11
Back:   8, 9

假设节点遍历成本Ct = 1.0和交叉点成本Ci = 10.0。我们首先发现不分裂的成本是Cns = N * Ci = 12 * 10.0 = 120.0

现在我们依次遍历每个轴并对候选分割平面进行增量扫描,以查看分割成本是否更便宜。第一个分割平面是p = <x,0>。我们有Nl = 0Np = 2Nr = 10(即左侧,平面和平面右侧的三角形数)。平面中的两个三角形是数字6和7(左面)。所有其他人都在右边。

现在执行SAH(p,V,Nl,Nr,Np)功能。这将分割平面,体素V分割,以及左/右/平面三角形的数量。它计算击中左(平)体素的概率为Pl = SA(Vl)/SA(V) = 50/150 = 1/3,右概率为Pr = SA(Vr)/SA(V) = 150/150 = 1。现在它运行两次成本函数;首先使用左侧的平面三角形,然后使用右侧的平面三角形分别获得ClCr

费用函数C(Pl,Pr,Nl,Nr)返回bias * (Ct + Ci(Pl * Nl + Pr * Nr))

Cl:左侧是平面三角形的成本(Nl = 2Nr = 10

bias = 1我们没有偏见,因为左右体素都不是空的 Cl = 1 * (1 + 10(1/3 * 2 + 1 * 10)) = 107.666

Cr:右侧有平面三角形(Nl = 0Nr = 12

bias = 0.8空单元格偏见发挥作用 Cr = 0.8 * (1 + 10(1/3 * 0 + 1 * 12)) = 96.8

该算法确定Cr = 96.8优于将两个三角形分割成平坦的单元格Cl = 107.666,并且优于不在全部Cns = 120.0分割体素。没有其他候选人分裂被发现更便宜。因此,我们分成一个空的左子,一个包含所有三角形右子。当我们递归到正确的孩子继续树木建造时,我们执行与上面完全相同的步骤。这只是因为最大深度终止标准,这不会导致堆栈溢出。结果树非常深。

该论文声称已经考虑过这种事情:

  

剪裁期间,必须特别注意正确处理   特殊情况,如“扁平”(即零体积)细胞,或其中的情况   可能发生数值不准确(例如,对于非常薄的细胞)   与三角形的大小相比)。例如,我们必须确保   不要“夹住”位于扁平单元格中的三角形。请注意这样   案件不是罕见的例外,但实际上是由SAH鼓励的,   因为它们通常会产生最低的预期成本。

     

这种局部近似很容易陷入局部最小值:As   当地贪婪的SAH高估了CV(p),它可能会停止细分   即使正确的成本表明进一步细分。在   特别是,局部近似可能导致提前终止   对于需要在侧面分开扁平细胞的体素:很多   场景(特别是建筑场景)包含几何   轴对齐盒子的形式(灯具,桌腿或桌面,   。 。 。 ),在这种情况下,双方必须“剃掉”,直到   空的内部暴露。对于错误选择的参数,或何时   使用与我们使用的成本函数不同的成本函数(特别是   在叶估计中加入常数成本的那些,   递归可以提前终止。虽然这是一个成熟的退出   也可以以硬编码的方式避免 - 例如,只执行   非扁平电池的自动终止测试 - 我们建议遵循我们的   公式,在这种情况下不会发生过早退出。

我做错了吗?我怎么能纠正这个?

0 个答案:

没有答案