1

在 three.js 项目中(可在此处查看),我有 500 个立方体,大小相同,并且都是静态定位的。在这些立方体中的每一个上,有五个面始终保持相同的颜色;然而,第六面的颜色可以动态更新,并且这种修改发生在单个帧中的许多立方体上,也发生在大多数帧中。

我已经能够以几种不同的方式来实现这个场景,但我对我尝试过的任何东西的性能并不完全满意。我知道我一定还没有找到正确的技术,或者我没有完全正确地实施一种技术。从性能的角度来看,改变这些立方体面的颜色同时保持每个立方体的独立性的最佳方法是什么?

这是我到目前为止所尝试的:

  1. 创建 500 个单独的 CubeGeometry 和 Mesh 实例。更改几何面的颜色,如此处答案中所述:更改立方体面的颜色。到目前为止,这种方法对我来说效果最好,但 500 个相同的几何形状似乎不太理想,尤其是因为我无法通过良好的 GPU 实现常规的 60fps。在这里渲染大约需要 11-20 毫秒。

  2. 创建一个 CubeGeometry 并在 500 个 Mesh 实例中使用它。创建一个 MeshBasicMaterials 数组,为每个 Mesh 创建一个 MeshFaceMaterial。其中五个 MeshBasicMaterial 实例是相同的,代表每个立方体的五个静态着色面。创建一个唯一的 MeshBasicMaterial 以添加到每个 Mesh 的 MeshFaceMaterial。使用 thisMesh.material.materials[3].uniforms.diffuse.value.copy(newColor) 更新这种独特材质的颜色。这种方法的渲染速度比第一种方法慢很多,90-110ms,这让我感到惊讶。可能是因为 500 个立方体,每个立方体 6 种材料 = 3000 种要处理的材料???

您能提供的任何建议将不胜感激!

4

1 回答 1

0

我发现three.js 为场景中的每个网格执行WebGL 绘制,这才是真正影响我性能的原因。我研究了 yaku 关于使用 BufferGeometry 的建议,我确信这将是一条很好的路线,但使用 BufferGeometry 似乎相对困难,除非你有大量的 WebGL/OpenGL 经验。

但是,我遇到了一个非常有效的替代解决方案。我仍然为我的 500 个立方体中的每一个创建了单独的网格,但随后我使用 GeometryUtils.merge() 将这些网格中的每一个合并为一个通用几何图形来表示整个立方体组。然后我使用该组几何体来创建组网格。GeometryUtils.merge() 的解释在这里

这种策略特别好的地方在于,您仍然可以访问属于您合并的基础几何/网格的所有面。在我的项目中,这让我仍然可以完全控制我想要控制的面部颜色:

// For 500 merged cubes, there will be 3000 faces in the geometry.
// This code will get the fourth face (index 3) of any cube.
_mergedCubesMesh.geometry.faces[(cubeIdx * 6) + 3].color
于 2013-08-06T01:12:06.643 回答