【问题标题】:Render heavy model / mesh on three.js在 three.js 上渲染重型模型/网格
【发布时间】: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.WebGL2Renderer would ONLY support BufferGeometry。)

标签: javascript google-chrome memory three.js


【解决方案1】:

您的纹理非常大,而且您不需要它们,因为您的模型已烘焙顶点颜色,其中包括烘焙光照。因此,您的模型也不需要 UV。

使用ColladaLoader2,和这个模式。它应该可以工作。

var loader = new THREE.ColladaLoader();

loader.load( 'BigModel.dae', function ( collada ) {

        var dae = collada.scene;

        dae.traverse( function( child ) {

            if ( child instanceof THREE.Mesh ) {

                child.geometry.removeAttribute( 'uv' ); // you don't need it

                child.material = new THREE.MeshBasicMaterial( { // scene lights not required

                    vertexColors: THREE.VertexColors // you have them, use them

                } );

                scene.add( child );
            }

        } );

} );

three.js r.86

【讨论】:

  • 感谢@WestLangley,我尝试使用 ColladaLoader2,它适用于较小的纹理。但正如你所说,我正在尝试使用模型内部的颜色而不是纹理。不幸的是,如果我移除 UV,我将看不到我的模型。我检查了我的网格几何体并且没有颜色。请参阅:my mesh geometry。有什么建议吗?
  • 我之前投入了大量精力测试您的两个模型,并且加载了具有位置、颜色和 uv 属性的模型。该演示仅使用顶点颜色,响应速度非常快。
猜你喜欢
  • 2020-03-29
  • 2012-12-11
  • 1970-01-01
  • 2016-12-10
  • 2012-03-06
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多