KhronosGroup / glTF

glTF – Runtime 3D Asset Delivery
Other
7.15k stars 1.14k forks source link

Inconsistent object field naming in Material for generic properties #2420

Open spnda opened 3 months ago

spnda commented 3 months ago

The name, extras, and extensions fields exist on every object, in that order, and always at the end as the last fields. However, for the Material object these fields come first, as declared here in the JSON schema: https://github.com/KhronosGroup/glTF/blob/082d5a98f479c37dff18767982d1431fc6c014fd/specification/2.0/schema/material.schema.json#L9-L11

Is there any reason for this inconsistency? I'm interested since I want to speed up the JSON deserialization in fastgltf by assuming a certain field order, that is consistent with the spec, when I can safely detect the asset was serialized using the library. And it feels wrong to me that these three fields appear at the beginning here instead of the end.

lexaknyazev commented 3 months ago

RFC 8259 that defines JSON format says:

An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.

JSON parsing libraries have been observed to differ as to whether or not they make the ordering of object members visible to calling software. Implementations whose behavior does not depend on member ordering will be interoperable in the sense that they will not be affected by these differences.

glTF does not define (let alone require) any specific order of object properties.

lexaknyazev commented 3 months ago

That said, we'll update the schema file for consistency.

javagl commented 3 months ago

It may be worth noting that these properties are actually not defined in the material, for example, but at https://github.com/KhronosGroup/glTF/blob/082d5a98f479c37dff18767982d1431fc6c014fd/specification/2.0/schema/glTFProperty.schema.json#L6 (which material is ""inheriting"" from, as far as one can say this for JSON schema...)

(EDIT: The point is that the order can even be different in the "base" definition and the ""inheriting"" one...)

spnda commented 2 months ago

glTF does not define (let alone require) any specific order of object properties.

Is there any way I could put some hidden or meaningless tag somewhere into the glTF file that still conforms with the spec? I am planning on writing a Parser that would try and detect that tag, and then if it exists use a parser that is a lot quicker since it assumes a certain field order. Perhaps something in the Asset object, or some fake extension I could add to extensionsUsed like EXT_fastgltf_field_order? I still want the assets to be compatible with other loaders and tools, without them noticing this hidden tag.

lexaknyazev commented 2 months ago

Assuming that the flag should be located as close as possible to the beginning of the file, I'd suggest adding something to the extras property of the root glTF object.


{
  "extras": {
    "fastgltfFieldOrder": true
  },
  "asset": {
    "version": "2.0"
  }
}
spnda commented 2 months ago

hmm though I am not sure how we'll that'd work in a generic library, since I currently just forward the extra object's JSON as a string to the user. And when exporting glTF's I essentially ask the user for the object string, and it'd be hard or at least a little hacky to add another field into that object... And what about other loaders... would they be fine with that extra field just existing? Is it the norm to ignore unknown fields when working with JSON? I don't know much of the glTF ecosystem and quirks of JSON loaders apart from what exists for C++.

lexaknyazev commented 2 months ago

The spec explicitly defines extras as a place for application-specific data, thus it's valid for it to have any value.