如何在Three.JS中将两个BufferGeometries合并成一个BufferGeometry?

3
如何在ThreeJS中将两个缓冲区几何体合并为一个THREE.BufferGeometry
var modelGeometry = null;

geometry = new THREE.CylinderGeometry( 10, 10, 10 );

if (modelGeometry == null)
{
    modelGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
    console.log(modelGeometry);
}

bufGeometry = new THREE.SphereBufferGeometry( 20 , 20, 20 );

var mesh = new THREE.Mesh( bufGeometry, material );

modelGeometry.merge(mesh.geometry, mesh.matrix);

没有对modelGeometry做任何处理。如何正确合并这些几何体?


我认为缓冲几何体的合并不正确。尝试合并常规几何体:THREE.CylinderGeometryTHREE.SphereGeometry - WestLangley
看起来BufferGeometry的合并函数存在一个bug。 - Evgy
1
BufferGeometry.merge() 目前不支持索引的 BufferGeometry,而这是你在示例中使用的。(three.js r.75) - WestLangley
有没有不使用索引缓冲几何体来绘制这些基元的方法? - Evgy
BufferGeometry.toNonIndexed()。但是我重申我的第一个评论。 - WestLangley
BufferGeometry.toNonIndexed() 非常有趣,谢谢!合并普通几何体会导致浏览器页面崩溃。 - Evgy
2个回答

3

奇怪的是,在BufferGeometry上调用merge()方法给了我一些错误,但是有一个解决方法:

  1. 合并两个Geometry对象;
  2. 转换为BufferGeometry;
  3. 添加到Mesh中。

以下是对我有效的操作:

    var modelGeometry = new THREE.Geometry();

    cylGeometry = new THREE.CylinderGeometry( 10, 10, 10 );

    // if (modelGeometry == null)
    // {
    //     modelGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
    //     console.log(modelGeometry);
    // }

    modelGeometry.merge(cylGeometry);

    sphereGeometry = new THREE.SphereGeometry( 20 , 20, 20 );

    modelGeometry.merge(sphereGeometry);

    bufGeometry = new THREE.BufferGeometry().fromGeometry(modelGeometry);

    var mesh = new THREE.Mesh( bufGeometry, material );

    scene.add(mesh);

这也是我的第一次尝试。但是,当需要合并更多几何体时,这个技巧就不起作用了——浏览器在加载脚本时会崩溃...我只需要合并BufferGeometry。 - Evgy
@Evgy 为什么你需要合并这些几何体?如果只是为了将它们放在同一组中,你可以将它们添加到 Object3D 中,否则我不知道。 - leota
我需要加载一个非常大的模型到GL缓冲区,该模型由小的原始几何体创建。使用几何对象会导致浏览器在几百个对象处崩溃。将模型加载到场景中并分割为多个网格和许多独立的BufferGeometries可以提供更快的速度和更少的内存使用,但我仍然需要优化代码,合并几何体的一个网格速度很快,但还不够... 我唯一的希望就是最终只有一个BufferGeometry的网格。 - Evgy
@Evgy Tricky。由于merge()不再适用,这变得非常困难。 - leota
这种方法对我来说非常有效,可以处理5000个PlaneGeometry! - Holger Ludvigsen

2

我会整晚跳舞。完成了!

sumPosArr = new Float32Array(poslen);
sumNormArr = new Float32Array(normlen);
sumUvArr = new Float32Array(uvlen);

var postotalarr = new Array();

sumPosCursor = 0;
sumNormCursor = 0;
sumUvCursor = 0;

for (a = 0; a < objects.length; a++ )
{
    var posAttArr = objects[a].geometry.getAttribute('position').array;

    for (b = 0; b < posAttArr.length; b++)
    {
        sumPosArr[b + sumPosCursor] = posAttArr[b];
    }

    sumPosCursor += posAttArr.length;


    var numAttArr = objects[a].geometry.getAttribute('normal').array;

    for (b = 0; b < numAttArr.length; b++)
    {
        sumNormArr[b + sumNormCursor] = numAttArr[b];
    }

    sumNormCursor += numAttArr.length;


    var uvAttArr = objects[a].geometry.getAttribute('uv').array;

    for (b = 0; b < uvAttArr.length; b++)
    {
        sumUvArr[b + sumUvCursor] = uvAttArr[b];
    }

    sumUvCursor += uvAttArr.length;

}

modelGeometry.addAttribute('position', new THREE.BufferAttribute(sumPosArr, 3 ));
modelGeometry.addAttribute('normal', new THREE.BufferAttribute(sumNormArr, 3 ));
modelGeometry.addAttribute('uv', new THREE.BufferAttribute(sumUvArr, 2 ));

1
THREE.BufferGeometry 无法合并索引几何体。 - Evgy

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