Three.js:更新几何与替换

时间:2015-01-28 22:23:41

标签: javascript performance three.js

我有一个使用ExtrudeGeometry的大量对象的场景。这些中的每一个都需要更新每个框架,其中正在挤出的形状正在改变,以及挤出量。使用d3的voronoi算法生成形状。

See example.

现在我通过从场景中删除每个对象并在每个帧中重绘它来实现此目的。这非常昂贵并且导致性能问题。有没有办法编辑每个网格/几何而不是从场景中删除?这对性能有帮助吗?或者是否有更有效的重绘场景的方法?

我需要编辑挤出的形状和挤出量。

谢谢你看看!

2 个答案:

答案 0 :(得分:2)

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

你应该

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

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

  4. 之后,您可以使用mesh.updateMorphTargets()

    为网格设置动画。

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

答案 1 :(得分:2)

所以我设法提出了一种不必每次都重绘场景的方法,它大大提高了性能。

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

我就这样做了:

  1. 创建了一个"模板几何体" ExtrudeGeometry使用假人 10边多边形。

  2. 和以前一样,创建了一堆"点",这次分配每个 指出这些模板几何中的一个。

  3. 在每个帧上,迭代每个几何体,更新每个顶点 到新的那个(使用voronoi alg像以前一样)。

  4. 如果剩下额外的顶点,"束"他们到一个点。 (见http://github.com/mrdoob/three.js/wiki/Updates。)

  5. 现在看一下,这是一个非常简单的过程。在此之前,操纵每个顶点的想法对我来说似乎超凡脱俗,但它实际上并不是因为简单的形状而过于棘手!

    这里是我如何进行迭代,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;