【问题标题】:Looking for some pointers for voxelisation strategies寻找体素化策略的一些指示
【发布时间】:2026-01-17 17:30:01
【问题描述】:

体素化网格基本上意味着能够确定一个点(x,y,z)是在网格内部还是外部。

这里的网格只是一组原始三角形。位于网格之外意味着有一条来自该点(具有任何方向)的射线从任何角度都不与网格相交。

对于一个表现良好、封闭、不相交的网格,这很容易:在任何方向上追踪光线,如果相交的数量是奇数,则该点在内部。

但是对于由开放部分组成的“坏”网格,这很糟糕。例如,网格可以是两个立方体,它们由一个开放的圆柱体连接,该圆柱体插入两个立方体。

ZBuffer 渲染解决了这一问题。但这个问题适用于任何观点。对我来说,这个问题很明确,但解决起来并不明显。

我正在寻找有关如何解决此问题的一些指示。必须有大量的研究。有论文链接吗?或者我在如何思考这个问题上遗漏了什么?

【问题讨论】:

    标签: algorithm math 3d geometry


    【解决方案1】:

    如果您的网格上的所有表面都对它们具有“侧面性”,即它们具有正面和背面,这是可能的。

    然后要确定一个点是否在网格内,您可以从该点向任何方向追踪光线,并保持这样的交叉点计数:

    • 如果光线穿过背面并从正面射出(即从内向外射出),则添加一个。
    • 如果光线穿过正面并从背面射出(即从外部进入内部),则减一。
    • 如果网格表面是双面的,则不要添加或减去任何东西。

    如果最终计数为正,或者如果该点正好位于任何表面上,则该点位于网格内部。

    您需要添加一个限制,即永远不可能从网格外部看到表面的暴露背面。这相当于说网格应该始终从所有外部视点正确渲染,并打开背面剔除。

    对于具有立方体和开放圆柱体的示例,要使立方体成为实心的,它的表面应该是单面的(将它们设为双面意味着定义一个具有无限薄壁的空心立方体)。

    圆柱体的网格表面也必须是单面的,否则它也会有无限薄的壁,并且圆柱体内的点(不在立方体内)不会在网格内。只要圆柱体的末端卡在立方体内,限制就不会被打破,因为你永远看不到脸的背面。

    如果其中一个立方体被移除,则不满足限制,该算法将失败。

    【讨论】:

    • 我很欣赏这个答案,但我认为它不正确。与计算奇数/偶数交叉点相比,这是一个边际改进。最简单的情况是一架飞机。有了这个定义,我不想在里面。通过跟踪和计数,根据开始和方向,您可以在里面或外面。理想的算法会在每个方向上追踪一条光线(实际上不可能),如果有任何光线没有击中该点,则在外面。
    • 对于单个平面,您必须将面制作成双面(在这种情况下,根据需要,内部没有点)。将其设为单面会打破背面不暴露的限制。
    • 对。但我也想处理一个以其中一个平面为面的立方体。每一张脸都是一个断开的平面。如果我把它们做成单面的,里面的立方体就会在里面。如果我把它们做成双面的,它就会在外面。我怎么知道哪些多边形是单面的还是双面的?