【发布时间】:2017-07-20 08:33:18
【问题描述】:
我知道这是一个众所周知的问题,但我找不到好的答案。
我的使用情况
我使用three.js来展示通过无人机图片创建的3D模型(here an example)。
问题
我无法渲染重型模型(1M 顶点,2M 面):Chrome 或 WebGl 崩溃。
我尝试了什么
我在所有测试中都使用了 Threejs.org 示例,以确保不是我的代码不起作用。我在带有 --max_old_space_size=6144 标志的 x64 Chrome 上进行了测试。
- 使用 ColladaLoader 在 .dae 中导入模型 --> 使用 2.5Go 的 RAM 并且 Chrome 崩溃(显示“内存不足”)
- 使用 OBJLoader + MTLLoader 在 .obj 中导入模型 --> 使用 2.8Go 的 RAM 并且 WebGl 崩溃
- 我发布了很多关于 Three.js 和内存分配的帖子,但其中很多都谈到了从场景中移除对象
可能的解决方案
- 我看到 .stl(二进制)文件更紧凑,但据我所知 这些文件没有纹理,所以我不能使用它
- 使用 BinaryLoader(具有 GeometryBuffer 输出),但我需要将 .dae 或 .obj 转换为二进制文件,但我不知道该怎么做
- 将我的模型加载到多个部分而不是一次加载?但我没有看到任何有这种待遇的例子或帖子
如何重现
对于代码,我使用 Threejs.org 上的基本示例。对于模型:
- 如果您想尝试使用 .dae,您可以在 this folder 上找到一个工作示例 (WorkingModel.dae / .jpg) 和不工作的模型 (BigModel.dae / .jpg)
- 如果您想尝试使用 .obj,您可以在 this folder 上找到一个工作示例 (WorkingModel.dae / .jpg / .mtl) 和不工作的模型 (BigModel.dae / .jpg / .mtl )
有什么想法可以加载大的吗? 谢谢!
编辑 1:
我尝试在 SuccessCallback 中放置一个断点,以查看 RAM 的过载是在加载期间还是之后。我无法命中断点,所以 RAM 的过载在 SuccessCallback 之前。
然后我一步一步地在 ColladaLoader 中查找使用这么多 RAM 的原因。这是“调用堆栈”:
- myCollada.load()
- ColladaLoader.parse()
- Geometry.parse()
- Mesh.parse()
- Source.parse(命中 3 次)= +400mo 内存
- Vertices.parse = +0mo in RAM
- Triangles.parse = +1500mo in RAM
- this.geometry3js.computeVertexNormals() = RAM 超过 2600Mo 和 chrome 崩溃
我可以做任何其他测试来找出这个问题的原因吗? 谢谢
【问题讨论】:
-
您的模型只有 200 万张面孔,却使用 2.5GB 内存?听起来有些内存没有按应有的方式释放。我使用了多达 3500 万张面孔的模型(自定义格式,不是 dae 或 obj),虽然性能不是很好,但它不会导致浏览器崩溃。另外,我不喜欢下载随机文件,请问您能否提供一些有关它们的信息,例如文件大小和图像分辨率?
-
@TheJim01 感谢您的回答。我的 .dae 大小为 151MB,.jpg 大小为 30MB(分辨率:16384*16384)。我刚刚上传了我的模型on sketchfab,这样你就可以看到它,如果你想下载它。
-
显然您的模型将在 WebGL 中呈现和表现良好。我建议首先在您的代码中放置一些断点,以查看
ColladaLoader是否曾经达到其完成回调,以及此时内存是否已经失控。没有到达断点,或者内存过剩表明加载程序存在问题。在合理的内存使用情况下命中断点告诉我们,其余代码对加载的数据做了坏事。 -
嗨@TheJim01,我按照你的建议做了,我用结果更新了我的帖子。谢谢!
-
尝试使用
ColladaLoader2。原来的ColladaLoader使用Geometry类,虽然很容易理解,但它创建了大量的JavaScript 对象,但不如替代方案BufferGeometry高效。ColladaLoader2使用BufferGeometry并非巧合。 :) (顺便说一句,我不知道他们的计划是否改变了,但我上次听说,THREE.WebGL2Rendererwould ONLY support BufferGeometry。)
标签: javascript google-chrome memory three.js