bevyengine / bevy

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

Bevy panics with certain skinned meshes #9021

Open nicopap opened 1 year ago

nicopap commented 1 year ago

Bevy version

main on fd32c6f0ec2

What you did

I tried to import a glTF file derived from blender's Snow.

What went wrong

Bevy crashes with this wonderfully cryptic error and not much more information:

ERROR wgpu::backend::direct: Handling wgpu errors as fatal by default    
thread '<unnamed>' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 1303, Vulkan)>`
    In a draw command, indexed:true indirect:false
      note: render pipeline = `pbr_opaque_mesh_pipeline-e1505v0`
    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

Why it happens

Under certain conditions (I'm still trying to find them out), an Entity will have a SkinnedMesh component, but the SkinnedMeshInverseBindposes asset for inverse_bindposes Handle will not exist.

This causes SkinnedMeshJoints::build to return None:

https://github.com/bevyengine/bevy/blob/982e33741de20241e4c1c3b46659b7da39dd8a2c/crates/bevy_pbr/src/render/mesh.rs#L239

When it returns None, extract_skinned_meshes will not add the SkinnedMeshJoints to the render-world-extracted Entity as per:

https://github.com/bevyengine/bevy/blob/982e33741de20241e4c1c3b46659b7da39dd8a2c/crates/bevy_pbr/src/render/mesh.rs#L288-L293

This is problematic, because the Entity in question will regardless have a Handle<Mesh> with skinning vertex attributes. Bevy's renderer checks those attributes to chose the bind group layout and shader for rendering the mesh:

https://github.com/bevyengine/bevy/blob/982e33741de20241e4c1c3b46659b7da39dd8a2c/crates/bevy_pbr/src/render/mesh.rs#L666-L668

(this is called by the Prepass and MeshPipeline)

But lo! the render impl of SetMeshBindGroup needs the SkinnedMeshJoints component, and its index, to comply with the bind group layout required by the skinning shader variant:

https://github.com/bevyengine/bevy/blob/982e33741de20241e4c1c3b46659b7da39dd8a2c/crates/bevy_pbr/src/render/mesh.rs#L1228-L1233

Now, we have a mismatch in bind group layout! And we get the wgpu panic.

Suggested improvements

mockersf commented 1 year ago

blender is crashing for me when trying to export this model as a gltf. Could you try to reduce the model as much as possible and still reproduce the issue?

Zoomulator commented 1 year ago

I just got this panic, but it only happened once! I was unable to trigger it again running the same build.


2023-07-28T09:46:53.736071Z ERROR wgpu::backend::direct: Handling wgpu errors as fatal by default 

thread '<unnamed>' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 230, Vulkan)>`
    In a draw command, indexed:true indirect:false
      note: render pipeline = `pbr_prepass_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  

', [HOME]\.cargo\registry\src\index.crates.io-6f17d22bba15001f\wgpu-0.16.3\src\backend\direct.rs:3019:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Encountered a panic in exclusive system `bevy_renthread 'Compute Task Pool (1)' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', [HOME]\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_render-0.11.0\src\pipelined_rendering.rs:135:45```
Zoomulator commented 1 year ago

Managed to reproduce it by accident! Was trying to create a new instance of a mesh from a gltf scene that had been spawned via SceneBundle. I was cloning the mesh handle and spawning a new PbrBundle with it and it panics every time.

Minimal reproduction here: bevy_gltf_mesh_panic.zip

Update: Realized now that it's because the copy is missing the SkinnedMesh component. Cloning that to the new entity fixed it for me. But I guess missing bind poses are part of the problem at large.

eastside commented 1 year ago

Aggressive Googling led to me this issue! I'm hitting the exact same error when rendering a SceneBundle from a .gltf with animation and bone data.

I've also got a minimal reproducible here which includes the .gltf assets.

In my case, I generated the .gltf from an Unreal Engine Skeletal Mesh with a dancing animation applied. It seems to be a valid .gltf by all accounts: I'm able to load it in a variety of (non-Bevy) viewers without problems (the mesh is skinned and the animation works).

I noticed that if I spawned a PbrBundle from the mesh and material in the scene, Bevy would render it just fine. So, something being wrong with the skeletal data seemed to make sense to me. (But I can't make heads or tails of the wgpu code that raises this error.)

nicopap commented 1 year ago

Thank you all for the small reproducible models. I've some clue as to what is going on, but I needed some lighter models to test it on. I'm going to spend some times today on this

mockersf commented 1 year ago

I have a fix in https://github.com/bevyengine/bevy/pull/9338, could you test if it works on all your cases?

eastside commented 1 year ago

I have a fix in #9338, could you test if it works on all your cases?

Woohoo! I tested your branch on my mini repro and it did the trick! Great work!