bevyengine / bevyengine/bevy

Bevy panics with certain skinned meshes

Open
#9,021 7 comments 4 reactions 0 assignees View on GitHub
A-Animation A-glTF A-Rendering C-Bug C-Usability I-Crash
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.