rerun-io / rerun

Visualize streams of multimodal data. Fast, easy to use, and simple to integrate. Built in Rust using egui.
https://rerun.io/
Apache License 2.0
6.24k stars 290 forks source link

glb/gltf files import fails if extension in `extensionsRequired` list is not present #7253

Open SeaOtocinclus opened 3 weeks ago

SeaOtocinclus commented 3 weeks ago

"Regression with the Asset3D support"

To Reproduce

Try to load the mesh "5462893327580.glb" shared here 5462893327580.glb.zip

v0.16 -> Can load v0.17/0.18 -> Can't load

WARN  re_space_view_spatial::mesh_cache] Failed to load mesh "5462893327580": invalid glTF: extensionsRequired[0] = "KHR_texture_transform": Unsupported extension;

Expected behavior

Wumpf commented 3 weeks ago

It look like the gltf loader library we use previously ignored the requiredExtension field of the glb/gltf. The spec mandates that loading fails if a loader doesn't support any of the extensions listed as required by a mesh. So the loader behaves now according to that spec. That said, obviously all the other data should be able to be loaded so we can at least try to display it, but this requires us to either downgrade (& fix upstream) or change our gltf library.

Meanwhile, you'll have to remove this extension from the required list.

Here's your mesh as GLTF:

{
  "asset": {
    "generator": "glTF-Transform v4.0.0",
    "version": "2.0"
  },
  "accessors": [
    {
      "type": "VEC3",
      "componentType": 5126,
      "count": 2432,
      "max": [
        36.395713806152344,
        4.665484428405762,
        76.97759246826172
      ],
      "min": [
        -36.5335807800293,
        -5.6504364013671875,
        -76.97759246826172
      ],
      "bufferView": 0,
      "byteOffset": 0
    },
    {
      "type": "VEC3",
      "componentType": 5126,
      "count": 2432,
      "bufferView": 0,
      "byteOffset": 12
    },
    {
      "type": "VEC2",
      "componentType": 5126,
      "count": 2432,
      "bufferView": 0,
      "byteOffset": 24
    },
    {
      "type": "SCALAR",
      "componentType": 5123,
      "count": 8091,
      "bufferView": 1,
      "byteOffset": 0
    }
  ],
  "bufferViews": [
    {
      "buffer": 0,
      "byteOffset": 0,
      "byteLength": 77824,
      "byteStride": 32,
      "target": 34962
    },
    {
      "buffer": 0,
      "byteOffset": 77824,
      "byteLength": 16184,
      "target": 34963
    }
  ],
  "samplers": [
    {
      "magFilter": 9728,
      "minFilter": 9984,
      "wrapS": 33071,
      "wrapT": 33071
    },
    {
      "magFilter": 9729,
      "minFilter": 9987,
      "wrapS": 10497,
      "wrapT": 10497
    },
    {
      "magFilter": 9729,
      "minFilter": 9987,
      "wrapS": 33071,
      "wrapT": 33071
    }
  ],
  "textures": [
    {
      "source": 0,
      "sampler": 0
    },
    {
      "source": 2,
      "sampler": 1
    },
    {
      "source": 3,
      "sampler": 1
    },
    {
      "source": 1,
      "sampler": 2
    }
  ],
  "images": [
    {
      "name": "base",
      "uri": "5462893327580_img0.jpg"
    },
    {
      "name": "metallicRoughness",
      "uri": "5462893327580_img1.jpg"
    },
    {
      "name": "normal",
      "uri": "5462893327580_img2.jpg"
    },
    {
      "name": "occlusion",
      "uri": "5462893327580_img3.jpg"
    }
  ],
  "buffers": [
    {
      "uri": "5462893327580_data.bin",
      "byteLength": 94008
    }
  ],
  "materials": [
    {
      "name": "Smartphone_Body_Material",
      "doubleSided": true,
      "pbrMetallicRoughness": {
        "baseColorTexture": {
          "index": 0
        },
        "metallicRoughnessTexture": {
          "index": 3
        }
      },
      "normalTexture": {
        "index": 1,
        "extensions": {
          "KHR_texture_transform": {
            "offset": [
              0.0078119998797774315,
              0.0078125
            ],
            "scale": [
              8.000791549682617,
              15.752901077270508
            ]
          }
        }
      },
      "occlusionTexture": {
        "index": 2,
        "extensions": {
          "KHR_texture_transform": {
            "offset": [
              0.0078119998797774315,
              0.0078125
            ],
            "scale": [
              8.000791549682617,
              15.752901077270508
            ]
          }
        }
      }
    }
  ],
  "meshes": [
    {
      "primitives": [
        {
          "attributes": {
            "POSITION": 0,
            "NORMAL": 1,
            "TEXCOORD_0": 2
          },
          "mode": 4,
          "material": 0,
          "indices": 3
        }
      ]
    }
  ],
  "nodes": [
    {
      "name": "smartphone_xiaomi13_Hot3D",
      "scale": [
        0.0010000000474974513,
        0.0010000000474974513,
        0.0010000000474974513
      ],
      "mesh": 0
    }
  ],
  "scenes": [
    {
      "name": "Scene",
      "nodes": [
        0
      ]
    }
  ],
  "scene": 0,
  "extensionsUsed": [
    "KHR_texture_transform"
  ],
  "extensionsRequired": [
    "KHR_texture_transform"
  ]
}

Notice the last bit: extensionsRequired. If you only specify it as "used" instead of "required", it still loads fine. Here's the file with this change repacked as glb for illustration purposes: fixed.glb.zip

Keeping this issue open since Rerun should handle this regardless.

Wumpf commented 3 weeks ago
SeaOtocinclus commented 2 weeks ago

Thank you @Wumpf for looking into this and tracing back how I could find a workaround.

emilk commented 2 weeks ago

From the changelog it looks like we just need to set the allow_empty_texture flag: https://github.com/gltf-rs/gltf/blob/main/CHANGELOG.md

EDIT: no, allow_empty_texture was not enough to fix this

emilk commented 2 weeks ago

Pinning gltf to =1.4.0 des not solve the issue either, weirdly enough. I think we need to bite the bullet and do a patch to gltf if we want to support loading meshes with errors.