zeux / meshoptimizer

Mesh optimization library that makes meshes smaller and faster to render
MIT License
5.49k stars 473 forks source link

gltfpack: gltf model lost some 'scene' information when compressed by gltfpack #723

Closed rarest closed 1 month ago

rarest commented 1 month ago

There are two meshes and two scenes the origin gltf model: meshes:

"meshes": [
    {
      "primitives": [
        {
          "attributes": {
            "POSITION": 1,
            "NORMAL": 2
          },
          "indices": 0,
          "material": 0
        },
        {
          "attributes": {
            "POSITION": 4,
            "NORMAL": 5
          },
          "indices": 3,
          "material": 1
        }
      ]
    },
    {
      "primitives": [
        {
          "attributes": {
            "POSITION": 1,
            "NORMAL": 2
          },
          "indices": 0,
          "material": 2
        },
        {
          "attributes": {
            "POSITION": 4,
            "NORMAL": 5
          },
          "indices": 3,
          "material": 3
        }
      ]
    }
  ]

scenes:

"scenes": [
    {
      "name": "estate_day",
      "nodes": [
        0
      ]
    },
    {
      "name": "estate_night",
      "nodes": [
        1
      ]
    }
  ]

Use gltfpack v0.21 and the following command to compress model

./gltfpack -i origin.gltf -o originMeshopt.gltf -cc

or

./gltfpack -i origin.gltf -o originMeshopt.glb -cc

After then, origin two meshes are merged into one, and the 'estate_night' nodes information is lost meshes:

"meshes": [{
    "primitives": [{
        "attributes": {
            "POSITION": 0,
            "NORMAL": 1
        },
        "indices": 2,
        "material": 0
    }, {
        "attributes": {
            "POSITION": 3,
            "NORMAL": 4
        },
        "indices": 5,
        "material": 1
    }, {
        "attributes": {
            "POSITION": 6,
            "NORMAL": 7
        },
        "indices": 8,
        "material": 2
    }, {
        "attributes": {
            "POSITION": 9,
            "NORMAL": 10
        },
        "indices": 11,
        "material": 3
    }]
}]

scenes:

"scenes": [{
    "name": "estate_day",
    "nodes": [0]
}, {
    "name": "estate_night"
}]

In the origin model, the two meshes is reused, only the material is different,thanks.

origin.zip originMeshopt.zip

rarest commented 1 month ago

with -v option

input: 2 nodes, 2 meshes (4 primitives), 4 materials, 0 skins, 0 animations, 0 images
input: 4 mesh primitives (1344 triangles, 1794 vertices); 4 draw calls (4 instances, 1344 triangles)
output: 4 mesh primitives (1344 triangles, 1726 vertices); 4 draw calls (4 instances, 1344 triangles)
output: 1 nodes, 1 meshes (4 primitives), 4 materials
output: JSON 3014 bytes, buffers 10848 bytes
output: buffers: vertex 9363 bytes, index 1477 bytes, skin 0 bytes, time 0 bytes, keyframe 0 bytes, instance 0 bytes, image 0 bytes
zeux commented 1 month ago

Thanks! This was a bug in mesh processing when multiple scenes are involved. You can work around this for now using -kn flag, as the bug should only manifest when gltfpack flattens the node hierarchy (which is the default), but this should be fixed in the next version as well.

rarest commented 1 month ago

Nice project, very efficiently👍🏻👍🏻