Skip to content

Conversation

@javagl
Copy link
Contributor

@javagl javagl commented Aug 30, 2025

Addresses #317

This is a DRAFT, to illustrate some possible approaches.


The first part of the current state (commit e96ed32) is a minor generalization of the GltfExtensionValidators class.

Until now, this class only offered a function called validateGltfExtensions. This did call the glTF extension validators that have been implemented within the 3D Tiles Tools. It simply did call them, one by one, by name.

The generalization here is: It now registers these validators in an extensionName -> GltfExtensionValidator lookup. This allows the implementation to simply iterate over this lookup and call them generically.
More importantly: This also allows the class to offer a function isRegistered(extensionName: string) : boolean that allows checking whether a certain extension is implemented as part of the 3D Tiles Validator (this will be used in the filtering - see below)


The second part (commit f11875f ) is the very drafty part for filtering out certain issues that are generated by the glTF Validator.

Some context:

The 3D Tiles Validator calls the glTF Validator for each relevant tile content. The glTF Validator generates a validation report. This validation report is translated into the ValidationIssue-based format of the 3D Tiles Validator. So the glTF Validator output ends up as the list of "causes" for a CONTENT_VALIDATION_ERROR/WARNING/INFO.

The 3D Tiles Validator already does offer functionality for filtering validation results. So one could, in theory, define some ValidationIssueFilter to filter out the unwanted glTF Validator issues from the final ValidationResult. The reasons why I did not choose this option:

  • Depending on how many issues are generated by the glTF-Validator, this may cause the final ValidationResult to become huge. I think that it can make sense to filter out unwanted warnings at an earlier place - namely, where they are created.
  • Related to that: Some warnings that may have to be filtered out are very "context specific". Trying to filter them out, post-hoc, from the full ValidationResult could 1. involve very complex ValidationIssueFilter conditions, and 2. more importantly: make it necessary to derive that context information by ~"searching other messages" in the full ValidationResult

So what is done here now:

The issues that are generated by the glTF Validator are translated into ValidationIssue objects. These will become the "causes" of the corresponding CONTENT_VALIDATION_ERROR/WARNING/INFO of the 3D Tiles Validator.

There is now a draft function filterCauses that receives these validation issues, for one glTF asset, and can implement different filter criteria.

One of the filter criteria is that the issues with the message
"Cannot validate an extension as it is not supported by the validator: '"
are filtered out for all extensions that are "registered" according to the GltfExtensionValidators.isRegistered(name) function.

A dummy implementation of certain filter criteria for KHR_texture_basisu is shown in the current state: It filters out issues

  • about the unsupported extension itself
  • about the invalid media/MIME type image/ktx2
  • about unrecognized image formats

Note that these are just dummy implementations. For example, the "Image format not recognized." message could also be caused for WEBP images! A proper filter would have to inspect the glTF, and see whether this message is really caused by a KTX texture.

@javagl
Copy link
Contributor Author

javagl commented Oct 17, 2025

Yes, the progress here is slow. I only occasionally carve out some time for this. It's all about priorities.

The last commit adds some generalization for the validation issue filtering. Ironically, this currently focusses on an extension that is not implemented as part of the 3D Tiles Validator, namely KHR_texture_basisu. The presence of this extension usually causes a bunch of issues:

  • "Cannot validate an extension as it is not supported by the validator: 'KHR_texture_basisu'."
  • "Invalid value 'image/ktx2'. Valid values are ('image/jpeg', 'image/png')."
  • "This object may be unused."
  • "Image format not recognized."

For example, for a tileset with a single GLB with KTX:

{
  "date": "2025-10-17T18:30:17.121Z",
  "numErrors": 0,
  "numWarnings": 1,
  "numInfos": 0,
  "issues": [
    {
      "type": "CONTENT_VALIDATION_WARNING",
      "path": "SimpleTextureWithKtx.glb",
      "message": "SimpleTextureWithKtx.glb caused validation warnings",
      "severity": "WARNING",
      "causes": [
        {
          "type": "CONTENT_VALIDATION_WARNING",
          "path": "SimpleTextureWithKtx.glb",
          "message": "Content SimpleTextureWithKtx.glb caused validation warnings",
          "severity": "WARNING",
          "causes": [
            {
              "type": "CONTENT_VALIDATION_INFO",
              "path": "/extensionsUsed/0",
              "message": "Cannot validate an extension as it is not supported by the validator: 'KHR_texture_basisu'.",
              "severity": "INFO"
            },
            {
              "type": "CONTENT_VALIDATION_WARNING",
              "path": "/images/0/mimeType",
              "message": "Invalid value 'image/ktx2'. Valid values are ('image/jpeg', 'image/png').",
              "severity": "WARNING"
            },
            {
              "type": "CONTENT_VALIDATION_INFO",
              "path": "/images/0",
              "message": "This object may be unused.",
              "severity": "INFO"
            },
            {
              "type": "CONTENT_VALIDATION_WARNING",
              "path": "/images/0",
              "message": "Image format not recognized.",
              "severity": "WARNING"
            }
          ]
        }
      ]
    }
  ]
}

This can be confusing and distracting, given that this extension is in fact widely supported.

Omitting some implementation details (that may still change): The last change here defines a processCauses function that can be defined for glTF extension validators that are part of the 3D Tiles Validator. This function can... do whatever it wants, essentially, to filter a given list of validation issues.

Usually, this will mean that it will just omit the message that says
"Cannot validate an extension as it is not supported by the validator: ...."
for the extensions that in fact are supported by the 3D Tiles Validator.

But usually, this implies that there are other issues reported by the glTF validator. So I implemented that function for the case of KHR_texture_basisu, to also omit the issues that refer to one of the /images/N, where the N is one of the images that are referred to by the KHR_texture_basisu extension.

The filtered result is the following:

{
  "date": "2025-10-17T18:35:28.955Z",
  "numErrors": 0,
  "numWarnings": 0,
  "numInfos": 1,
  "issues": [
    {
      "type": "CONTENT_VALIDATION_INFO",
      "path": "SimpleTextureWithKtx.glb",
      "message": "SimpleTextureWithKtx.glb caused validation infos",
      "severity": "INFO",
      "causes": [
        {
          "type": "CONTENT_VALIDATION_INFO",
          "path": "SimpleTextureWithKtx.glb",
          "message": "Content SimpleTextureWithKtx.glb caused validation infos",
          "severity": "INFO",
          "causes": [
            {
              "type": "VALIDATION_INFO",
              "path": "SimpleTextureWithKtx.glb",
              "message": "Omitted 4 issues that have been created due to the lack of support of the KHR_texture_basisu extension in the glTF validator",
              "severity": "INFO"
            }
          ]
        }
      ]
    }
  ]
}

I thought that it could make sense to still create that single INFO, just saying that what users receive may not be the full truth, but a filtered truth. (For extensions that are validated by the 3D Tiles Validator, such a message would not be necessary).

Some of this raises questions about possible configurability. Maybe some aspects of the behavior should be configurable via the validation options. But these should usually just boil down to some flags, and the details can be decided later.

@javagl
Copy link
Contributor Author

javagl commented Oct 18, 2025

An example for how that fitering infrastructure could be applied is now implemented (as a draft) for EXT_structural_metadata and EXT_mesh_features.

There is a function processCauses for this extension. This function is simply used for the interface implementation when the corresponding validator is registered.

This function will be called with the list of causes/issues that are generated by the glTF validator, and return the filtered result. It will

  • remove the issue about the EXT_structural_metadata extension not being supported
  • remove all issues that say "This object may be unused" for a buffer view or texture that actually is used by the extension

The latter is solved pragmatically: There are functions that compute the indices of buffer views or textures that are used, by drilling through the raw glTF JSON (defaulting to {} or [] everywhere), and returning the list of used indices. A utility function
GltfExtensionIssues.isObsoleteIssueAboutUnusedObject(issue, "bufferViews", usedBufferViewIndices);
checks whether the issue is such a message, allowing to filter it out accordingly.

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

Successfully merging this pull request may close these issues.

2 participants