we occasionally encounter GLTF files that contain inconsistent materials and primitives, where the material has a texture but the primitive has no texture coordinates.
This causes CesiumJS to crash with a fragment shader compilation error. Generally GL_OES_standard_derivatives extension is not supported (not really the issue) followed by ‘v_texCoord_0’ undeclared identifier.
The file does report an error from GLTF validator, and I’ve identified the triggering circumstance. However, hitting the error tends to stop all Cesium rendering. As we can have user-provided data, this can make it so that one bad file added by a user can prevent use of the viewer.
Is there a good way to trap this in all cases (model, inside a tileset, etc) and not stop the renderer?
Or fallback to not using the textured material if the primitive is incompatible?
The easiest way to see a problem is to view it in the extension for VSCode. The Cesium renderer fails with shader compilation issue. The other renderers ignore the problem.
I’ll find a code sample from static HTML using the latest Cesium build shortly.
I agree that it would be preferable for CesiumJS to handle this error (and similar errors) more gracefully. A hard crash should be avoided, even if the input data is complete garbage. And in this case, one could consider to print an error message and still render the asset, with a default material.
But beyond that, the more general question is: Which kinds of errors can be “ignored” (and how)?
There is no blanket answer for that. But a reasonable distinction is:
When a glTF asset it valid, then it must be possible to render it.
When a glTF asset is invalid, then it may not be possible to render it. (Even though the viewer should not crash…)
The asset.generator field of the asset says THREE.GLTFExporter. If this asset really has been generated by this exporter (and not modified afterwards), then it might be worth to file this as an issue report in the three.js repository: The exporter should certainly not generate invalid assets.
I can’t see any discussion of this missing attribute case in the GLTF spec at glTF™ 2.0 Specification. Missing normals are discussed and must be generated. It appears most tools simply use zero for missing UV attributes, but the correct behaviour is not defined.
As you say, the primary goal is to avoid the renderer crash. Rejecting the material entirely and using a default material would suffice, or using a default UV value to retain more of the desired material may make it easier to identify the problem geometry.
The validator at KhronosGroup/glTF-Validator reports the error MESH_PRIMITIVE_TOO_FEW_TEXCOORDS, and the reference viewer at glTF Sample Viewer renders by apparently ignoring the UV coords.
For context, I’ve found this kind of model from more than one source, typically editing software that has material libraries. Materials can be assigned to arbitrary primitives, often without much consideration of whether the primitive is compatible with the material. Sometimes editors and viewers provide texture coordinate generation (e.g. NVidia Omniverse). If the result is then exported to GLTF, this situation can result. Ideally the tools would not do this, possibly producing multiple versions of materials to suit different primitives.
This integer value is used to construct a string in the format TEXCOORD_<set index> which is a reference to a key in mesh.primitives.attributes (e.g. a value of 0 corresponds to TEXCOORD_0). A mesh primitive MUST have the corresponding texture coordinate attributes for the material to be applicable to it.
Type: integer
Required: No, default: 0
Minimum: >= 0
The file does not define the texCoord value of the baseColorTexture. The default value for the texCoord is 0. Therefore, the mesh primitive MUST have a TEXCOORD_0 attribute. But it doesn’t have one. That’s an error.
The infrastructure around glTF, including the specification and the validator, should make it easy to produce valid glTF assets spot invalid assets at the producing side, and free the consuming side from the burden of considering each and every possible error, and figure out workarounds.
(Long term, this would “pollute” the ecosystem with invalid assets, and more frequently raise the exact question that we’re talking about here: “9 out of 10 viewers are ignoring a certain error - why isn’t your viewer ignoring this error as well?”)
I see the point of trying to prevent crashes - and that’s certainly something that has to be discussed and evaluated more generally. But for the specific case, one could consider to just make sure that the glTF is valid. Attached is a version without the texture in the material (thus, not requiring any texture coordinates).