Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple buffers, duplicate URIs? #2446

Open
donmccurdy opened this issue Sep 27, 2024 · 4 comments
Open

Multiple buffers, duplicate URIs? #2446

donmccurdy opened this issue Sep 27, 2024 · 4 comments

Comments

@donmccurdy
Copy link
Contributor

I came across a file recently containing three buffers, all sharing the same URI:

  "buffers": [
    {
      "uri": "glTF.bin",
      "byteLength": 8160
    },
    {
      "uri": "glTF.bin",
      "byteLength": 8160
    },
    {
      "uri": "glTF.bin",
      "byteLength": 8160
    }
  ],

No validation errors were found, and viewers I tested (three.js, babylon.js, playcanvas) seemed fine, but it did break processing in glTF Transform, which tried to overwrite the buffer repeatedly. The file also contained valid buffer views pointing to each buffer.

My impression is that this is suboptimal, but technically valid, does that seem correct?

@javagl
Copy link
Contributor

javagl commented Sep 27, 2024

I think that there are no constraints that disallow this, so would agree that this is technically valid.

I just created a Triangle with such duplicate buffers:

TriangleDuplicateBuffer.zip

Just for the heck of it, I did two further tests:

I declared them once with "byteLength": 44 (correct) and once with "byteLength": 43 ("wrong"). And interestingly, the validator reports both to have "byteLength": 44. (So it apparently overwrites the declared byte length with the length of the actual .bin file...)

I also thought that it could be difficult to clearly define when two buffer declarations are actually equal. So (locally) I also tried using
"uri": "./subdirectory/../Triangle_data.bin",
as the URI for the second one. This resolves to the same URI. And in fact, the validator reports this as "uri": "Triangle_data.bin", (i.e. some form of "normalized" version of the URI). But there probably are cases where such a normalization is far more difficult (or maybe even impossible).

So ... when this is allowed, it might raise some questions for implementors. Consider an example like the Triangle.gltf, but with two triangles, each referring to its own accessors and buffer views and buffer. And only on the lowest level - namely, on the level of the uri of the buffer - these buffers are equal. Now, when someone does
gltf.meshes[0].primitives[0].attributes["POSITION"].set(0, 1234.567);
will this affect both triangles, because the underlying, most raw Buffer objects that have been read from the .bin file are identical because they have the same URI?

(This is probably beyond what the glTF spec can cover. But for things like glTF-Transform, there will be an answer to this question, and regardless what the answer is: It might be different from what someone expects...)

@lexaknyazev
Copy link
Member

the validator reports both to have "byteLength": 44. (So it apparently overwrites the declared byte length with the length of the actual .bin file...)

The resources section of the report provides information about the actual resources, in this case the file's byte length.

Thes spec says:

The byte length of the referenced resource MUST be greater than or equal to the buffer.byteLength property.

so it's valid to declare a buffer's byte length less than the actual file.

@javagl
Copy link
Contributor

javagl commented Sep 27, 2024

Yes, but I considered it to be a corner case for establishing any concept of "equality" between buffers: If two buffers with the same uri were be disallowed by the spec, it would raise the question of whether they should also be disallowed when they had different byteLengths.

Even before that, the concept of "equality" can already be difficult for the uri itself. (I'd have to start by looking up whether URIs can have things like fragments here).

When buffers with duplicate URIs are valid, some questions about what "duplicate" means don't even come up. Other details (e.g. whether clients SHOULD or MAY read these .bin files twice, and store the memory twice) are probably too implementation specific to be covered by the spec.

@donmccurdy
Copy link
Contributor Author

donmccurdy commented Sep 28, 2024

Planned fix in glTF Transform:

No plans to round-trip such files as-is — with multiple buffers pointing to overlapping ranges of the same underlying file — but reading and writing should at least handle the files gracefully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants