Three.js - 合并多个几何体/网格并删除共同区域

3
我试图将两个几何体/网格(红色和蓝色)合并成一个唯一的。但是在创建新的几何体并应用geometry.merge()后,我发现所有内部顶点和面仍然存在(绿色区域)。
我想要删除所有额外的信息,因为它会在渲染的面上产生视觉故障,并且我无法正确计算合并体积...我需要像最后一张图片那样的东西,一个只包括最小外部/外部面和顶点的单个网格,去除内部的。

enter image description here

我尝试使用ThreeCSG来减去网格,但发现在加载大型模型时会经常崩溃。我还尝试应用光线投射器来检测共同的面,但这对于大型模型的性能影响很大。
ThreeCSG是唯一的好选择吗?但由于我无法在每个模型上使用它,所以应该放弃它。我想应用一些快速的东西,不那么依赖网格的三角形数量。

1
你可以将ThreeCSG代码转换为生成器,并添加yield,这样浏览器就不会将你弹出。请参阅我的描述:http://stackoverflow.com/questions/34631657/for-loops-are-disturbing-rendering/34820834#34820834。 - fluffybunny
@spacorum,我更新了我的答案,并附上了一个示例... - Wilt
@fluffybunny 我仍在努力理解yield的概念。这只是几行代码,但对我来说非常高级。我根本无法理解它的作用以及如何将其应用于我的当前问题... - spacorum
与您尝试通过交错网格进行的操作相比,我的代码显得很蠢,不够先进。 - fluffybunny
我的代码有点混乱。Javascript是单线程的,如果你的代码在规定时间内没有返回,浏览器会故意崩溃。通过在settimer中运行代码的小部分,然后再做另一个settimer来运行更多的代码,你可以逐步地通过算法。为了使用预先存在的具有大型for循环的代码变得“容易”,你可以使用javascript生成器(查找一下)将代码转换为可以在计时器链中运行的小块。 - fluffybunny
这听起来不错。我以一种更丑陋的方式使用这个概念,只有在我不需要用户等待辅助元素加载时才使用。但是我认为,如果在浏览器崩溃之前我无法完成它,那么我做错了。我仍在尝试找出最快的方法将如此多的网格合并成一个没有内部顶点的单个网格,目前CSG似乎可以很好地处理立方体/球体,但不能处理5-10Mb的加载模型。也许我正在强制推动Three.js/WebGL的极限?在Blender中进行这样的合并可能会让我的电脑发烫2-3分钟,想想就可怕。 - spacorum
1个回答

6
如果您使用ThreeCSG和布尔运算,应尝试从一开始定义对象为BSP树或节点。这将提供更精确的结果,并可能帮助您使较大的几何图形在不崩溃浏览器的情况下工作。
我制作了这里的演示,您可以看到我的意思。结果如下所示:

result of the boolean operations

  • 在左边,您可以看到我们在操作中使用的形状(仅用于可视化)。
  • 中间的布尔结果是通过从转换为BSP的THREE.BoxGeometry中减去转换为BSP的THREE.PlaneGeometry创建的。
  • 右侧的布尔结果是通过从本机BSP盒对象中减去本机BSP平面创建的。

正如您所看到的,中间结果有5个以上的顶点,也就意味着有更多的面(在顶部、两侧和底部各增加1个,在对角线平面上增加2个)。

如果您在此结果上执行另一个布尔运算,您将获得更多的点和顶点。您的BSP树将呈指数增长...!


换句话说,每次布尔操作都会使您的BSP树变得越来越大,从而变慢,并且最终可能会崩溃。如果您想进行大量的布尔操作,请尝试创建本机BSP形状以获得更好的结果,而不是使用转换后的three.js几何图形进行布尔操作。
因此,建议不要使用转换后的three.js几何图形进行布尔操作,而应该创建本机BSP形状。
myBSP = new ThreeBSP( geometry );

做:

var polygons = [
    // define your polygons using new ThreeBSP.Polygon( vertices )
];

var node = new ThreeBSP.Node(polygons);

myBSP = new ThreeBSP(node);

然后进行布尔运算...


我非常喜欢使用JSFiddle来玩耍 :) 感谢您的时间。我可能很幸运:我可以从形状构建原始网格,因为我知道每个顶点的位置。因此,将其更改为多边形,然后按照您的策略进行操作应该相对容易!我正在努力实现这一点。 - spacorum
@spacorum 很酷,听起来不错。可惜没有原生的Three.js几何体与BSP定义更兼容。但是一些自定义代码就可以了。 - Wilt
经过我的第一次尝试,我可以说我能够将网格加载为多边形而不是形状(我发现它有点慢!)。但是,在应用.subtract()之后,机器在减去前20或30个网格后崩溃了。实际上,我想要的是.union()而不是subtract,但这个操作似乎在这里不起作用(它只保留了我的第一个网格)。即使在你的fiddle中它也能工作。回到这个问题,我必须找到一种方法! - spacorum
我必须说,我从来没有在一个对象上执行超过10个布尔运算。ThreeCSG没有进行优化,它能够处理的BSP树大小有一定限制,肯定会使事情变慢。祝你好运! - Wilt
@spacorum,合并几何体有什么进展吗? - Wilt
嗨,Wilt!抱歉,我错过了通知。 好吧,我找到了一个好方法,使用交集。 但是这种方法不能再优化了,而且当加载具有大量面的巨型模型时仍然存在一些问题(大量的射线检查会使浏览器崩溃)。因此,虽然可以完成,但代价很高。 - spacorum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接