具有10000个网格的Three.js性能优化

时间:2017-10-17 20:15:00

标签: performance three.js

我在Three.js中加载.obj模型,然后从其面创建独立的网格,以获得真正有趣的动画。但问题是如此多的网格表现非常糟糕。

实际上,具有10000个面孔的单个网格效果很好。但是分开的10000个网格(从这些面创建)工作很糟糕 - 即使没有动画,也只是静态场景。

如何通过保存此类动画来优化性能?

链接:http://intelligence-group.ru/test.html

以下是创建网格的代码:

` obj_loader.load(
        '/assets/models/zeus.obj',
        function(object) {

            var material = new THREE.MeshPhongMaterial( {
                    color: "#eeeeee",
                    shading: THREE.FlatShading,
                    metalness: 0,
                    roughness: 0.5,
                    refractionRatio: 0.25
            } );

            var face = new THREE.Face3( 0, 1, 2 );

            for (var i = 0; i < object.children.length; i++) {
                var child = object.children[i];
                var geometry = new THREE.Geometry().fromBufferGeometry(child.geometry);

                for (var i = 0; i < geometry.faces.length; i++) {
                    var new_geometry = new THREE.Geometry();
                    var a = geometry.faces[i].a;
                    var b = geometry.faces[i].b;
                    var c = geometry.faces[i].c;
                    new_geometry.vertices.push(geometry.vertices[a]);
                    new_geometry.vertices.push(geometry.vertices[b]);
                    new_geometry.vertices.push(geometry.vertices[c]);

                    new_geometry.faces.push( face );
                    new_geometry.computeFaceNormals();

                    var mesh = new THREE.Mesh( new_geometry, material );
                    group.add( mesh );
                }

                full_orig_array(group); //animation function - not the reason of bad optimization!
            }

            scene.add(group);
        }
    );`

重要提示:完成动画后,我用一个网格(来自装载机的原始对象)替换10 000个网格 - 然后你可以看到性能的大幅提升。它不是关于动画 - 我检查过它:即使没有动画,万网也有相同的不良表现。

据我所知,它涉及每个网格中不同的几何形状。但我不知道如何解决这个问题(

请注意我不会复制几何图形 - 每个网格的几何图形都是唯一的。那就是问题!

2 个答案:

答案 0 :(得分:2)

在stackoverflow上已经有很多关于drawcalls和状态变化的性能成本的答案,所以我不会进入那个。你需要得到drawcalls的数量,以有效地渲染。如何做到完全取决于你的确切问题和你的创造力。

我的建议是使用单个BufferGeometry:您可以在单个缓冲区几何体中设置所有顶点位置的动画。您需要将状态(平移,旋转等)保持在几何体之外,但您可以编写可以自由转换所有三角形的代码,就好像它们是单个对象一样。

答案 1 :(得分:1)

您从许多drawcalls和webgl状态更改中获得开销。渲染为一个网格是单次绘制调用vs 10.000。

您可以使用三个InstancedBufferGeometry将这些合并到一个调用中,而不会复制几何图形(从而节省内存和开销)。

遗憾的是,这个类不适用于默认材质,阴影等。它是一个相当低级别的结构。

我写了一个进一步的抽象,它应该与THREE.Mesh处于同一水平,并与阴影,AO,深度等一起工作。

https://www.npmjs.com/package/three-instanced-mesh