Three.js:更新几何体 vs 替换

4
我有一个场景,其中有很多使用ExtrudeGeometry的对象。每个对象需要在每一帧更新,被挤出的形状和挤出量都在变化,这些形状是使用d3的voronoi算法生成的。 查看示例。 目前,我通过从场景中删除每个对象并在每一帧重新绘制它们来实现这一点。这非常耗费资源,导致性能问题。是否有一种方法可以编辑每个网格/几何体而不是从场景中删除它们?这样做会提高性能吗?或者有更有效的重绘场景的方法吗?
我需要同时编辑挤出的形状和挤出量。
谢谢您的关注!
2个回答

3

如果您不改变面数,可以使用变形目标 http://threejs.org/examples/webgl_morphtargets.html

您应该:

  1. 创建您的几何体
  2. 克隆几何体并对其进行修改,例如您的几何柱的最大长度
  3. 将这两个几何体设置为基础几何体的变形目标,例如

    baseGeo.morphTargets.push( { name: "targetName", vertices: [ modifiedVertexArray ] } );

之后,您可以通过mesh.updateMorphTargets() 来动画化网格

请参见 http://threejs.org/examples/webgl_morphtargets.html


谢谢你向我展示这个。它可能不适用于我在使用d3的voronoi算法生成形状。这些形状可以有任意数量的边(通常约为4或5)。此外,没有简单的方法来预测每个形状的外观,所以我不确定在每个状态之间进行缓动是否有效。你认为采用逐帧动画的变形方法仍然能提高性能吗? - AlexKempton
你只能更新缓冲区的内容,不能调整缓冲区的大小(这非常耗费资源,基本上相当于创建新几何体)。你可以通过预先分配更大的缓冲区,然后保持不需要的顶点折叠/隐藏来模拟调整大小。 - Bob Woodley
最近我一直在使用Web Worker进行大型重构拓扑工作,如果你觉得性能不够好,可以尝试一下这个。基本上,你可以在Web Worker中生成几何形状,在post事件中将其添加回场景并删除旧的。 - Flux

2

我成功地找到了一个不需要每次重新绘制场景的方法,它极大地提高了性能。

http://jsfiddle.net/x00xsdrt/4/

这就是我的做法:

  1. 使用一个虚拟的10边形多边形,用ExtrudeGeometry创建一个“模板几何体”。

  2. 像之前一样,创建一堆“点”,这次为每个点分配一个模板几何体。

  3. 每一帧迭代每个几何体,将每个顶点更新为新的顶点(仍然使用voronoi算法)。

  4. 如果剩余额外的顶点,则将它们“扎堆”成一个单独的点。(见http://github.com/mrdoob/three.js/wiki/Updates。)

现在看来,这是一个相当简单的过程。之前,操纵每个顶点的想法对我来说似乎超凡脱俗,但对于简单的形状来说,实际上并不是太棘手!

这是我进行迭代的方法,polycColumn仅是具有相同多边形的2项数组:

// Set the vertex index
var v = 0;

// Iterate over both top and bottom of poly
for (var p=0;p<polyColumn.length;p++) {

    // Iterate over half the vertices
    for (var j=0;j<verts.length/2;j++) {

        // create correct z-index depending on top/bottom
        if (p == 1) {
            var z = point.extrudeAmount;
        } else {
            var z = 0;
        }

        // If there are still legitimate verts
        if (j < poly.length) {

            verts[v].x = poly[j][0];
            verts[v].y = poly[j][1];
            verts[v].z = z;

        // If we've got extra verts, bunch them up in the same place
        } else {

            verts[v].x = verts[v - 1].x;
            verts[v].y = verts[v - 1].y;
            verts[v].z = z;
        }

        v++;
    }
}

point.mesh.geometry.verticesNeedUpdate = true;

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