bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
34.11k stars 3.32k forks source link

bevy panics when spawning GLTF Mesh asset without associated bones/armature #10810

Open dmlary opened 7 months ago

dmlary commented 7 months ago

Bevy version

v0.12

What you did

Bevy panics when you spawn a Mesh from a GLTF asset that has an attached armature. The GLTF file I'm working with contains a single cube, with a single bone inside it. When I spawn it as #Scene0 it works fine, but when I only want to spawn the #Mesh0/Primitive0 it panics.

When I spawn it, the application crashes with:

2023-11-29T22:44:06.310929Z ERROR log: Handling wgpu errors as fatal by default thread '<unnamed>' panicked at /Users/dmlary/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-0.17.2/src/backend/direct.rs:3056:5: wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 2, Metal)>`
    In a draw command, indexed:true indirect:false
      note: render pipeline = `pbr_opaque_mesh_pipeline`
    The pipeline layout, associated with the current render pipeline, contains a bind group layout at index 2 which is incompatible with the bind group layout associated with the bind group at 2

Source code used to load the asset.

use bevy::prelude::*;

fn main() {
    let mut app = App::new();

    app.add_plugins((DefaultPlugins,))
        .add_systems(Startup, setup)
        .run();
}

fn setup(
    mut commands: Commands,
    mut materials: ResMut<Assets<StandardMaterial>>,
    asset_server: Res<AssetServer>,
) {
    // XXX works fine
    // let scene = asset_server.load("cube-with-bone.glb#Scene0");
    // commands.spawn(SceneBundle { scene, ..default() });

    // XXX panics during render
    let mesh_handle: Handle<Mesh> = asset_server.load("cube-with-bone.glb#Mesh0/Primitive0");
    commands.spawn(MaterialMeshBundle {
        mesh: mesh_handle,
        material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
        ..default()
    });

    // camera
    commands.spawn(Camera3dBundle {
        transform: Transform::from_xyz(10.0, 12.0, 16.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });
}

Questions

Additional information

Zip file of both .blender and .glb files (thanks for the idea @alice-i-cecile): cube-with-bone.zip

blender file screenshot (because github no support gltf/blender files):

Screenshot 2023-11-29 at 4 51 51 PM

gltf file loaded in gltf viewer:

Screenshot 2023-11-29 at 5 01 38 PM

full-panic-output.txt

Another person brought up this issue in the discord recently: https://discord.com/channels/691052431525675048/1179374309882462239

Further background

The wider context for this is I'm working on a scene-less blender workflow for spawning objects, characters, etc from a GLTF file. I'm able to spawn the hierarchy from GltfNode[^spawn-url], but it panics if any Mesh had bones attached. Unless I'm missing something obvious, the Armature have been removed from the GltfNode, so I don't know that it should be spawned.

[^spawn-url]: spawn code in discord

alice-i-cecile commented 7 months ago

Can you upload a zip of the offending file? It'll make this much easier to reproduce :)

dmlary commented 7 months ago

Ohhh, yes! Zip files! GENIUS! cube-with-bone.zip (also edited issue to add it up there too)

CestcaVision commented 7 months ago

I tried to modify the gltf file, if i delete "JOINTS_0": 2,"WEIGHTS_0": 3, the asset loads successfully. I think this bug is caused by the fields "primitives" of gltf file with armature and the bindgroups of wgpu not matching.

  "meshes": [
    {
      "name": "fox1",
      "primitives": [
        {
          "attributes": {
            "POSITION": 0,
            "TEXCOORD_0": 1,
            /*delete*/"JOINTS_0": 2,
           /*delete*/"WEIGHTS_0": 3
          },
          "material": 0
        }
      ]
    }
  ],
FinecoFinit commented 4 months ago

Still not fixed?

dmlary commented 4 months ago

Still not fixed?

I'm not actively working on fixing this as it isn't immediately blocking me. Mostly I just opened the issue to document the behavior for anyone else who encounters it so they don't have to spend a lot of time debugging.

If you need bones in your model, you'll need to split it out into a Scene for now.

FinecoFinit commented 4 months ago

@dmlary I'm pretty new to Bevy and Rust, right now I'm trying to use shaders over 3d model. As I see I can't just add custom material to scenebundle, at least I didn't saw any example to it

dmlary commented 4 months ago

@dmlary I'm pretty new to Bevy and Rust, right now I'm trying to use shaders over 3d model. As I see I can't just add custom material to scenebundle, at least I didn't saw any example to it

You should be able to get some help with that by opening a discussion on the github (https://github.com/bevyengine/bevy/discussions), or in the help channel in the discord (https://discord.com/channels/691052431525675048/1019697973933899910)

SnowdenWintermute commented 3 months ago

I was having a similar thing happen when I spawn the mesh and later delete the bones. I made an example repo here:

https://github.com/SnowdenWintermute/delete-bones-bevy-crash

This is for Wasm but not sure if that matters. My error is

Caused by:
    In a RenderPass
      note: encoder = `main_opaque_pass_3d_command_encoder`
    In a draw command, indexed:true indirect:false
      note: render pipeline = `pbr_opaque_mesh_pipeline`
    Incompatible bind group at index 1 in the current render pipeline
      note: Should be compatible an with an explicit bind group layout with label = `skinned_mesh_layout`
      note: Assigned explicit bind group layout with label = `mesh2d_layout`
      note: Entry 1 not found in assigned bind group layout
FinecoFinit commented 2 months ago

Still not fixed!