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

Robust GLTF Extension Support #11350

Open
thepackett opened this issue Jan 15, 2024 · 2 comments
Open

Robust GLTF Extension Support #11350

thepackett opened this issue Jan 15, 2024 · 2 comments
Labels
A-Assets Load files from disk to use for things like images, models, and sounds C-Feature A new feature, making something new possible

Comments

@thepackett
Copy link
Contributor

GLTF High Level Overview

GLTF stands for Graphics Library Transmission Format, and is an industry standard file format for representing 3D scenes developed by the Khronos Group (known for OpenGL, Vulkan, etc). GLTF files can take two different forms:

  • .gltf which is a JSON file describing a 3D scene along with resources (.bin, images, etc) either stored externaly in binary/image/etc files, or internally in base64 encoded strings.
  • .glb which stores the gltf asset (JSON, .bin, images, etc) in a binary blob.

In addition to the core GLTF specification (which covers most things like textures, meshes, scenes, etc), GLTF also supports Extensions.

Extensions:

An Extension is additional data that can be appended to any JSON object in a gltf file to provide additional functionality. For example, the KHR_materials_ior extension appends a single float to a material that represents its Index of Refraction.

Extensions were designed to be an interoperable way to extend GLTF functionality without affecting the core GLTF specification, with unsupported extensions simply being ignored. However, some extensions do need to affect the core GLTF specification in a non-interoperable way. For example, EXT_meshopt_compression which appends pointers to buffers containing compressed mesh data makes the original non-compressed mesh buffer pointer optional (it may be included for interoperability, but it somewhat defeats the purpose to include both compressed and uncompressed data).

All extensions used must be listed in the root GLTF object's extensionsUsed array. If an extension produces a core GLTF specification non-compliant file, then the extension must be listed in the root GLTF object's extensionsRequired array.

GLTF Specification:

The full GLTF specification can be found here.

GLTF in Bevy

How it currently works:

Bevy currently uses gltf-rs to parse a .gltf file's bytes into a rust friendly data structure which is then used to fill out our internal GLTF representation with data.
Our internal GLTF representation covers the core GLTF specification, as well as Extras. However, Bevy does not currently support any extensions, GLTF compliant or non-compliant, and because of this we are missing out on a large number of very useful GLTF features.

Objective:

Bevy needs a flexible internal GLTF representation that can support GLTF compliant and GLTF non-compliant extensions, as well as a way for users to implement their own custom GLTF extensions.

After looking into every officially ratified GLTF extension, I found that only KHR_draco_mesh_compression, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, EXT_meshopt_compression, and EXT_texture_webp can create non-compliant gltf files. These extensions fall into two categories:

  • KHR_draco_mesh_compression, KHR_texture_basisu, KHR_texture_transform, EXT_meshopt_compression, and EXT_texture_webp all follow the pattern of making some part of the original gltf specification optional.
  • KHR_mesh_quantization is unique in that it allows mesh data to be represented by other data types than a float, which the original spec requires. It is also unique in that it is not possible to specify a fallback, and so if this extension is used it must be required.

With this in mind, we can come up with some (potentially unreasonable) goals for Bevy's GLTF implementation:

  • The internal representation must include all features in the core GLTF specification, but must also:
    • Allow Extensions to mark core GLTF data as optional.
    • Allow Extensions to change the data type of some core GLTF data.
    • Allow Extensions of Extensions to mark another extension's data as optional.
    • Allow Extensions of Extensions to change the data type of another extension's data.
  • Extensions must be able to specify how their data is loaded and saved.
    • This supports features such as compression.
    • This hopefully will allow there to be a single AssetLoader and AssetSaver for any combination of GLTF extensions.
    • Extensions must be able to report whether or not they will create a GLTF compliant file based on save settings.
  • Extensions must contain a list of other extensions which they are incompatible with.
  • Extensions must contain a list of other extensions which are required.

This list is not set in stone and may change as I work on implementing extensions.

@thepackett thepackett added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jan 15, 2024
@alice-i-cecile alice-i-cecile added A-Assets Load files from disk to use for things like images, models, and sounds and removed S-Needs-Triage This issue needs to be labelled labels Jan 15, 2024
@jdm
Copy link
Contributor

jdm commented Jan 15, 2024

Relevant: #11138

@thepackett
Copy link
Contributor Author

Relevant: #11138

I like #11138 as a good short term solution, but my hope with this issue is to develop a more robust solution for GLTF extensions in bevy since it is a very important part of the GLTF ecosystem. It's a significant undertaking which may take a while though, so I think it would be a good idea to have #11138 merged first. Any extension support is better than no extension support.

@alice-i-cecile alice-i-cecile changed the title Adding Extension Support to Bevy_Gltf Robust GLTF Extension Support Jan 15, 2024
github-merge-queue bot pushed a commit that referenced this issue Feb 21, 2024
Adopted #8266, so copy-pasting the description from there:

# Objective

Support the KHR_texture_transform extension for the glTF loader.

- Fixes #6335
- Fixes #11869 
- Implements part of #11350
- Implements the GLTF part of #399 

## Solution

As is, this only supports a single transform. Looking at Godot's source,
they support one transform with an optional second one for detail, AO,
and emission. glTF specifies one per texture. The public domain
materials I looked at seem to share the same transform. So maybe having
just one is acceptable for now. I tried to include a warning if multiple
different transforms exist for the same material.

Note the gltf crate doesn't expose the texture transform for the normal
and occlusion textures, which it should, so I just ignored those for
now. (note by @janhohenheim: this is still the case)

Via `cargo run --release --example scene_viewer
~/src/clone/glTF-Sample-Models/2.0/TextureTransformTest/glTF/TextureTransformTest.gltf`:


![texture_transform](https://user-images.githubusercontent.com/283864/228938298-aa2ef524-555b-411d-9637-fd0dac226fb0.png)

## Changelog

Support for the
[KHR_texture_transform](https:/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform)
extension added. Texture UVs that were scaled, rotated, or offset in a
GLTF are now properly handled.

---------

Co-authored-by: Al McElrath <[email protected]>
Co-authored-by: Kanabenki <[email protected]>
msvbg pushed a commit to msvbg/bevy that referenced this issue Feb 26, 2024
Adopted bevyengine#8266, so copy-pasting the description from there:

# Objective

Support the KHR_texture_transform extension for the glTF loader.

- Fixes bevyengine#6335
- Fixes bevyengine#11869 
- Implements part of bevyengine#11350
- Implements the GLTF part of bevyengine#399 

## Solution

As is, this only supports a single transform. Looking at Godot's source,
they support one transform with an optional second one for detail, AO,
and emission. glTF specifies one per texture. The public domain
materials I looked at seem to share the same transform. So maybe having
just one is acceptable for now. I tried to include a warning if multiple
different transforms exist for the same material.

Note the gltf crate doesn't expose the texture transform for the normal
and occlusion textures, which it should, so I just ignored those for
now. (note by @janhohenheim: this is still the case)

Via `cargo run --release --example scene_viewer
~/src/clone/glTF-Sample-Models/2.0/TextureTransformTest/glTF/TextureTransformTest.gltf`:


![texture_transform](https://user-images.githubusercontent.com/283864/228938298-aa2ef524-555b-411d-9637-fd0dac226fb0.png)

## Changelog

Support for the
[KHR_texture_transform](https:/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform)
extension added. Texture UVs that were scaled, rotated, or offset in a
GLTF are now properly handled.

---------

Co-authored-by: Al McElrath <[email protected]>
Co-authored-by: Kanabenki <[email protected]>
msvbg pushed a commit to msvbg/bevy that referenced this issue Feb 26, 2024
Adopted bevyengine#8266, so copy-pasting the description from there:

# Objective

Support the KHR_texture_transform extension for the glTF loader.

- Fixes bevyengine#6335
- Fixes bevyengine#11869 
- Implements part of bevyengine#11350
- Implements the GLTF part of bevyengine#399 

## Solution

As is, this only supports a single transform. Looking at Godot's source,
they support one transform with an optional second one for detail, AO,
and emission. glTF specifies one per texture. The public domain
materials I looked at seem to share the same transform. So maybe having
just one is acceptable for now. I tried to include a warning if multiple
different transforms exist for the same material.

Note the gltf crate doesn't expose the texture transform for the normal
and occlusion textures, which it should, so I just ignored those for
now. (note by @janhohenheim: this is still the case)

Via `cargo run --release --example scene_viewer
~/src/clone/glTF-Sample-Models/2.0/TextureTransformTest/glTF/TextureTransformTest.gltf`:


![texture_transform](https://user-images.githubusercontent.com/283864/228938298-aa2ef524-555b-411d-9637-fd0dac226fb0.png)

## Changelog

Support for the
[KHR_texture_transform](https:/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform)
extension added. Texture UVs that were scaled, rotated, or offset in a
GLTF are now properly handled.

---------

Co-authored-by: Al McElrath <[email protected]>
Co-authored-by: Kanabenki <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Assets Load files from disk to use for things like images, models, and sounds C-Feature A new feature, making something new possible
Projects
None yet
Development

No branches or pull requests

3 participants