如何优化在three.js中渲染多个球形几何体?

6

我希望优化three.js中sphereGeometry的渲染,因为它成为了我的程序瓶颈。以下是javascript程序:

var sphereThree = [];
for(var idSphere = 0; idSphere < numSphere; idSphere++){
    var sphereGeometry = new THREE.SphereGeometry(1.0);
    var sphereMaterial = new THREE.MeshLambertMaterial({color: 'rgb(255, 0, 0)'});

    sphereThree[idSphere] = new THREE.Mesh(sphereGeometry, sphereMaterial);

    sphereThree[idSphere].position.x = x[idSphere];
    sphereThree[idSphere].position.y = y[idSphere];
    sphereThree[idSphere].position.z = z[idSphere];

    scene.add(sphereThree[idSphere]);
}

如下链接所述:
- 使用Three.js动画一个百万字母
- 优化Three.js性能:模拟成千上万个独立移动的物体
它们指出我们不应该单独添加对象,最好同时添加相同类型的对象以进行优化。然而,由于我在这个领域还是新手,不知道如何使用SphereGeometry编写此优化代码。

如果有人知道如何使用SphereGeometry编写这些内容,或者知道一种有效的渲染许多(10,000或更多)球体的方法,能否教一下我们?

谢谢!

2个回答

20

你可以像这样重用几何体和材质:

var sphereGeometry = new THREE.SphereGeometry(1.0);
var sphereMaterial = new THREE.MeshLambertMaterial({color: 'rgb(255, 0, 0)'});

var sphereThree = [];
for(var idSphere = 0; idSphere < numSphere; idSphere++){
    sphereThree[idSphere] = new THREE.Mesh(sphereGeometry, sphereMaterial);

    sphereThree[idSphere].position.x = x[idSphere];
    sphereThree[idSphere].position.y = y[idSphere];
    sphereThree[idSphere].position.z = z[idSphere];

    scene.add(sphereThree[idSphere]);
}

1
谢谢您的回答!它起作用了,对于2000个粒子的情况,渲染时间变快了4.5倍!!顺便说一下,这种方法仅适用于粒子的颜色和大小相同的情况。您知道如何在每个粒子属性不同的情况下加快渲染时间吗? - eng27
4
创建一个 sphereGeometry,但使用多个 sphereMaterials 来改变颜色。至于大小,请使用 sphereThree[idSphere].scale.x = sphereThree[idSphere].scale.y = sphereThree[idSphere].scale.z = scale 来设置缩放。 - gman
谢谢,gman!你提出的想法使我们能够在不增加时间的情况下呈现不同大小的球体。然而,在我的应用程序中,多个sphereMaterials增加了渲染时间。无论如何,谢谢! - eng27
1
将一个变量移动到全局位置——“var texture1 = THREE.ImageUtils.loadTexture(“images/concrete.jpg”);”,效果天壤之别。感谢mrdoob! - fivedogit
@mrdoob,正如您所提到的,我已经创建了一些几何体并为每个网格应用了矩阵, mesh.applyMatrix(matrix4)效果很好,但是交集没有发生, 我需要创建多个几何体并将矩阵应用于几何体吗, 如果是这样,那么渲染时间和内存占用会增加吗? - Iam Coder
通过这样做,我们实现了深刻的性能提升。谢谢! - subvertallchris

0
如果球体的外观并不是很重要,您还可以将widthSegments和heightSegments参数设置为低于默认值的值。请参阅文档此处
基本上做如下操作:
var sphereGeometry = new THREE.SphereGeometry(1.0, 5, 4);

更新 我忘了提到,这应该在您尝试mrdoob的建议并且想要进一步优化时完成。加速效果不显著。


谢谢您的回答!虽然我尝试了您的想法,但对我的代码来说并不高效。渲染时间变得更快了,但是其他计算(用于确定球体之间的碰撞)却变得更加繁重了。 - eng27
@eng27,你说得对,这并不是一个很大的改进,但是你是如何测量碰撞检测运行时间的呢?由于面数较少,所以应该会更快。除非它针对默认面数进行了优化,否则我将在检查后再次更新我的答案。 - kon psych
感谢您的回复。我认为这个球体是一个“理想”的球体,因为我正在使用它来呈现物理模拟的结果。因此,在计算碰撞时,面数并不是很重要。然而,计算时间会在某种程度上增加。 - eng27
我相信你使用了自己的方法。这种差异在每次运行中都是可观测到的吗?在测量中始终要留有误差空间。希望你不会使用像 Chrome 开发者工具这样的工具来声明。它测量的是时间百分比,而不是绝对值,所以如果某个方法的百分比降低,另一个方法的百分比就会增加。 - kon psych

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