Bevy glTF Considerations

2026-03-07

By Caitlin Sar Campbell

The situation at hand.

The amount of work that has been put into the Bevy glTF system is clear and evident. There is a ton of functionality that works really well and helps the engine shine.

In working on my game and continuing to learn the Bevy codebase, there is an issue that I think, while not threatening now, will only continue to grow into a larger and larger problem as time goes on.

This is the state of the gltf-rs dependency that Bevy uses in the bevy-gltf crate.

This crate is not well maintained, to the point where the same issue has been submitted multiple times over the years.

All three of these are for the same issue, adding KHR_texture_basisu support, and in my opinion all three were/are clean implementations against the existing gltf codebase.

If you look at the outstanding PRs, most of them are for adding one or another of the Ratified Khronos Extensions .

This is where the fundamental issue arises. While these extensions are not part of the core glTF 2.0 specification, they are de facto needed in order to use glTF as a modern 3D asset standard, particularly where glTF/GLB is the primary and preferred asset format.

As Bevy becomes more and more widely recognized as a game engine, it will become stranger and stranger that the only real options for textures are JPEG and PNG, both with their own issues and non-native GPU deficiencies.

Even worse, in my book, is telling current and future Bevy developers that "Bevy sort of hacks in KTX2 texture support in glTF files, but you need to use a special tool that turns your compliant glTF file into a non-compliant one BUT IT WORKS IN BEVY!"

What should we aim for?

Before continuing to consider resolutions, I think considering what would be desirable is worth doing.

Long Term

From a developer perspective, the ideal goal would be to make the glTF/GLB experience a first-class one.

The developer should be able to use glTF/GLB files without fear, without worrying about compatibility or the need to hack things in, in the same way that a Unity developer imports .unity assets knowing things will go smoothly.

Technologically speaking, I think this means we aim for FULL compatibility with all ratified Khronos extensions.

This is less daunting than it may seem. We already handle a good amount of these, and just need to parse the glTF JSON to hand it off to the relevant existing Bevy code.

Others are already in progress.

Others will need new code in Bevy or elsewhere.

In addition, I would propose that we consider adding selected vendor extensions including EXT_texture_webp and EXT_texture_avif (if we have AVIF support in the engine already). These are less important, but would lean into the first-class developer experience.

Short Term

In looking at what level of expanded glTF support we see in other game engines, we see this:

ExtensionGodotUnityBevy
KHR_animation_pointerX*
KHR_draco_mesh_compressionX*X
KHR_lights_punctualX*XX
KHR_materials_anisotropyX*X
KHR_materials_clearcoatX*XX
KHR_materials_diffuse_transmissionX*
KHR_materials_dispersionX*
KHR_materials_emissive_strengthX*X
KHR_materials_iorX*in progressX
KHR_materials_iridescenceX*
KHR_materials_sheenX*in progress
KHR_materials_specularX*in progressX
KHR_materials_transmissionX*in progressX
KHR_materials_unlitX*XX
KHR_materials_variantsX*X
KHR_materials_volumeX*in progressX
KHR_mesh_quantizationX*X
KHR_texture_basisuX*X
KHR_texture_transformX*XX
KHR_xmp_json_ldX*
EXT_lights_image_basedX*in progress
EXT_mesh_gpu_instancingX*X
EXT_meshopt_compressionX*X
EXT_texture_webpX*
KHR_materials_pbrSpecularGlossinessX*partial
*Godot docs don't list supported and unsupported extensions, but looking through the source I found nothing missing.
Unity imports via glTFast

I propose that, short term, we aim to be a superset of Unity, focusing on supporting the extensions they have that we don't.

Short term, we may consider adding EXT_texture_webp as well, since this would be trivial once we decide on an approach.

Potential Resolutions

There are several resolutions I could foresee. BUT the only resolution that I think would be actively harmful would be to continue to base bevy_gltf on gltf-rs without a long-term plan.

We should not pull a Warhammer 40k and build an empire around a slowly rotting corpse of a project. Not without a plan to lean less on the corpse at least.

Best Case - gltf-rs revival

If we can revive the project, either through a maintainer of gltf-rs becoming active or through the project adding a Bevy-vouched-for approver, this would be the best case.

With an understanding that the gltf-rs project owners may have certain requirements, we could agree to only make changes that do not interfere with those requirements.

This requires some buy-in from the gltf-rs owners, which may be impossible.

This would allow us to make these changes to benefit Bevy and the community as a whole.

Case 2 - gltf-rs fork

Another option is for a group of people to maintain a fork of the existing project. It will be more work, but the crate is well documented and has a test suite that could be expanded to reduce future labor.

Here we could start by cherry-picking the relevant existing PRs, and we would be halfway done with our long-term goals.

The advantage here is that we could use upstream labor in our efforts to maintain the crate. The whole wider community benefits.

Case 3 - do raw glTF I/O in-house as part of bevy-gltf

This is less bad than one might think. Right now we use gltf-rs and wrap our "user space" GltfExtensionHandler trait around it.

There are some existing extensions that are implemented in-house, namely khr_materials_anisotropy, khr_materials_clearcoat, and khr_materials_specular.

I think this approach is valid. My primary concern here is that we are still wrapping the code around a slowly rotting corpse. My secondary concern is that we lose out on upstream efforts.

I think there is a path forward if we take this approach.

In addition to adding all the extensions that make for a predictable first-class glTF experience, we slowly handle the core glTF features as well using the same code paths.

We have the khr_materials_anisotropy extension, but we could then add core_node_hierarchy that would handle a core glTF 2.0 feature.

We could do this slowly over time, one piece at a time, replacing one core feature at a time until we have core_*, where all glTF 2.0 core functionality is handled and wrapped around nothing.

This would let us slowly migrate away without replacing the world.

Conclusion / Key Points

  1. If glTF is our preferred asset format, we should make using it a first-class experience.
  2. The root cause of the existing glTF problems is gltf-rs not being well maintained.
  3. We can fix this root cause by reviving the core project, forking it, or bringing it in-house.
  4. No matter which way we go, we SHOULD & MUST not build an empire on a rotting corpse.