54 releases
Uses new Rust 2024
| 0.18.0 | Jan 13, 2026 |
|---|---|
| 0.18.0-rc.2 | Dec 30, 2025 |
| 0.17.3 | Nov 17, 2025 |
| 0.16.1 | May 30, 2025 |
| 0.3.0 | Nov 3, 2020 |
#2727 in Game dev
179,268 downloads per month
Used in 148 crates
(5 directly)
12MB
210K
SLoC
Plugin providing an AssetLoader and type definitions
for loading glTF 2.0 (a standard 3D scene definition format) files in Bevy.
The glTF 2.0 specification defines the format of the glTF files.
Quick Start
Here's how to spawn a simple glTF scene
fn spawn_gltf(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn((
// This is equivalent to "models/FlightHelmet/FlightHelmet.gltf#Scene0"
// The `#Scene0` label here is very important because it tells bevy to load the first scene in the glTF file.
// If this isn't specified bevy doesn't know which part of the glTF file to load.
SceneRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"))),
// You can use the transform to give it a position
Transform::from_xyz(2.0, 0.0, -5.0),
));
}
Loading parts of a glTF asset
Using Gltf
If you want to access part of the asset, you can load the entire Gltf using the AssetServer.
Once the Handle<Gltf> is loaded you can then use it to access named parts of it.
// Holds the scene handle
#[derive(Resource)]
struct HelmetScene(Handle<Gltf>);
fn load_gltf(mut commands: Commands, asset_server: Res<AssetServer>) {
let gltf = asset_server.load("models/FlightHelmet/FlightHelmet.gltf");
commands.insert_resource(HelmetScene(gltf));
}
fn spawn_gltf_objects(
mut commands: Commands,
helmet_scene: Res<HelmetScene>,
gltf_assets: Res<Assets<Gltf>>,
mut loaded: Local<bool>,
) {
// Only do this once
if *loaded {
return;
}
// Wait until the scene is loaded
let Some(gltf) = gltf_assets.get(&helmet_scene.0) else {
return;
};
*loaded = true;
// Spawns the first scene in the file
commands.spawn(SceneRoot(gltf.scenes[0].clone()));
// Spawns the scene named "Lenses_low"
commands.spawn((
SceneRoot(gltf.named_scenes["Lenses_low"].clone()),
Transform::from_xyz(1.0, 2.0, 3.0),
));
}
Asset Labels
The glTF loader let's you specify labels that let you target specific parts of the glTF.
Be careful when using this feature, if you misspell a label it will simply ignore it without warning.
You can use GltfAssetLabel to ensure you are using the correct label.
Supported KHR Extensions
glTF files may use functionality beyond the base glTF specification, specified as a list of required extensions. The table below shows which of the ratified Khronos extensions are supported by Bevy.
| Extension | Supported | Requires feature |
|---|---|---|
KHR_animation_pointer |
❌ | |
KHR_draco_mesh_compression |
❌ | |
KHR_lights_punctual |
✅ | |
KHR_materials_anisotropy |
✅ | pbr_anisotropy_texture |
KHR_materials_clearcoat |
✅ | pbr_multi_layer_material_textures |
KHR_materials_dispersion |
❌ | |
KHR_materials_emissive_strength |
✅ | |
KHR_materials_ior |
✅ | |
KHR_materials_iridescence |
❌ | |
KHR_materials_sheen |
❌ | |
KHR_materials_specular |
✅ | pbr_specular_textures |
KHR_materials_transmission |
✅ | pbr_transmission_textures |
KHR_materials_unlit |
✅ | |
KHR_materials_variants |
❌ | |
KHR_materials_volume |
✅ | |
KHR_mesh_quantization |
❌ | |
KHR_texture_basisu |
❌* | |
KHR_texture_transform |
✅** | |
KHR_xmp_json_ld |
❌ | |
EXT_mesh_gpu_instancing |
❌ | |
EXT_meshopt_compression |
❌ | |
EXT_texture_webp |
❌* |
*Bevy supports ktx2 and webp formats but doesn't support the extension's syntax, see #19104.
**KHR_texture_transform is only supported on base_color_texture, see #15310.
See the glTF Extension Registry for more information on extensions.
Bevy glTF
Dependencies
~48–87MB
~1.5M SLoC