如何在THREE.js GLTF导出中减小文件大小

时间:2019-01-29 17:02:52

标签: javascript three.js 3d filesize gltf

我正在THREE.js中构建Mancala游戏,它使用相当简单的形状和物理特性来提供比通常的俯视2D视图更内在的体验。可能是过大了,但这就是生命:)

我设法构建了一个我喜欢的板,但是由于它涉及少量的代码和组装周期,所以我认为我应该单独构建它,并将该对象导出为GLTF或GLB文件以加载到客户端中面向版本。麻烦的是,GLTFExporter函数会分出3或4MB的文件(即使是二进制文件),这并不是一个非常复杂的形状。 (OBJ甚至更糟。)我的问题是:THREE.js对象中的哪些内容可以导致导出文件增长得如此之快?为最大程度地减小大小,可以牺牲什么?

背景

我希望板子在外围和垃圾箱内部具有圆角,就像普通的板子一样,您可以buy online

enter image description here

经过ThreeCSG的多次实验后,我发现将Paul West's elegant RoundEdgeBox (2.0)用于外部框架要容易得多,剪掉顶部和底部边缘,然后在垃圾箱和较大的水池之间使用分隔线,简单的BoxGeometries:

enter image description here

该对象以GLTF格式导出到易于管理的170Kb左右。

要在型腔内部打圆,我用ExtrudeGeometry制作了一个PI / 2弧,该弧已合并到料仓的内部:

    // length is the height, size is the thickness
    let makeBorder = function(length, radius, size) {
        extrudeSettings.depth = length;
        let shape = new THREE.Shape();
        shape.moveTo(radius + size, 0 );
        shape.arc(-radius - size, 0, radius + size, 0, Math.PI / 2, false)
        shape.lineTo( 0, radius );
        shape.arc(0, -radius, radius, Math.PI / 2, 0, true)
        shape.lineTo( radius + size, 0 );

        let geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
        geometry.computeBoundingBox();
        return geometry;
    }

将这些四分之一弧合并为垃圾箱底部和垂直边缘的大小,您会得到一个非常不错的曲率:

enter image description here

不好的是,它给GLTF和GLB文件增加了几MB的信息。我很确定自己做对了所有显而易见的事情:

  • 我导出了对象,而不是整个场景
  • 我记下了电话号码 弧线段的数量在曲线看起来之前尽可能少 太吵了
  • 我使用了最简单的材料(没有图像)

只是盯着JSON版本的导出(GLTF),我发现最后一些我不需要的东西,例如pbrMetallicRoughness下的materials:

"materials": [
{
  "pbrMetallicRoughness": {
    "baseColorFactor": [
      0.6784313725490196,
      0.8470588235294118,
      0.9019607843137255,
      1
    ],
    "metallicFactor": 0.5,
    "roughnessFactor": 0.5
  }
}
]

但是我认为这并没有增加太多。有四个BufferViews,大小都很大。这是正常且必要的吗?

"bufferViews": [
{
  "buffer": 0,
  "byteOffset": 0,
  "byteLength": 35712,
  "target": 34962,
  "byteStride": 12
},
{
  "buffer": 0,
  "byteOffset": 35712,
  "byteLength": 35712,
  "target": 34962,
  "byteStride": 12
},
{
  "buffer": 0,
  "byteOffset": 71424,
  "byteLength": 35712,
  "target": 34962,
  "byteStride": 12
},
{
  "buffer": 0,
  "byteOffset": 107136,
  "byteLength": 23808,
  "target": 34962,
  "byteStride": 8
}
]

现在,我的攻击计划是将输出减少到一个盆和一个垃圾箱,然后在客户端上将它们克隆并缝合在一起。这并不困难,但我希望没有必要。鉴于此形状多次复制相同的子形状,是否有办法制作简洁的GLTF?

0 个答案:

没有答案