Bevy panics with certain skinned meshes
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version
main on fd32c6f0ec2
## What you did
I tried to import a glTF file derived from blender's [Snow](https://studio.blender.org/characters/snow/v2/).
## 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 '' panicked at 'wgpu error: Validation Error
Caused by:
In a RenderPass
note: encoder = ``
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` 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
- Panic in `extract_skinned_meshes` when `SkinnedMeshJoints::build` returns `None`. Since it will lead to a panic regardless, at least make it explicit why it panics.
- There is probably a more elegant minimal degradation route, with only an `error!` log, but not sure how an implementation would look like.
Contributor guide
Research direction
Start in crates/bevy_pbr/src/render/mesh.rs, examining SkinnedMeshJoints::build, extract_skinned_meshes, MeshPipeline/Prepass, and SetMeshBindGroup. Reproduce the Snow-derived glTF case and determine how a missing inverse_bindposes asset should be handled. Done means the case no longer reaches a wgpu bind-group-layout mismatch panic and has an explicit failure or graceful degradation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- computer-graphics, game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100