Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bevy panics with certain skinned meshes #9021

Open
nicopap opened this issue Jul 1, 2023 · 7 comments
Open

Bevy panics with certain skinned meshes #9021

nicopap opened this issue Jul 1, 2023 · 7 comments
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior C-Usability A simple quality-of-life change that makes Bevy easier to use P-Crash A sudden unexpected crash

Comments

@nicopap
Copy link
Contributor

nicopap commented Jul 1, 2023

Bevy version

main on fd32c6f

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:

let inverse_bindposes = inverse_bindposes.get(&skin.inverse_bindposes)?;

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

if let Some(skinned_joints) =
SkinnedMeshJoints::build(skin, &inverse_bindposes, &joint_query, &mut uniform.buffer)
{
last_start = last_start.max(skinned_joints.index as usize);
values.push((entity, skinned_joints.to_buffer_index()));
}

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:

fn is_skinned(layout: &Hashed<InnerMeshVertexBufferLayout>) -> bool {
layout.contains(Mesh::ATTRIBUTE_JOINT_INDEX) && layout.contains(Mesh::ATTRIBUTE_JOINT_WEIGHT)
}

(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:

match (skin_index, morph_index) {
(None, None) => set_bind_group(&[mesh_index]),
(Some(skin), None) => set_bind_group(&[mesh_index, skin.index]),
(None, Some(morph)) => set_bind_group(&[mesh_index, morph.index]),
(Some(skin), Some(morph)) => set_bind_group(&[mesh_index, skin.index, morph.index]),
};

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.
@nicopap nicopap added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen P-Crash A sudden unexpected crash C-Usability A simple quality-of-life change that makes Bevy easier to use labels Jul 1, 2023
@mockersf
Copy link
Member

mockersf commented Jul 3, 2023

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
Copy link
Contributor

Zoomulator commented Jul 28, 2023

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
Copy link
Contributor

Zoomulator commented Jul 30, 2023

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
Copy link

eastside commented Aug 1, 2023

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
Copy link
Contributor Author

nicopap commented Aug 1, 2023

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
Copy link
Member

mockersf commented Aug 2, 2023

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

@eastside
Copy link

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!

github-merge-queue bot pushed a commit that referenced this issue Aug 16, 2023
# Objective

- Fixes part of  #9021 

## Solution

- Joint mesh are in format `Unorm8x4` in some gltf file, but Bevy
expects a `Float32x4`. Converts them. Also converts `Unorm16x4`
- According to gltf spec:
https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
> WEIGHTS_n: float, or normalized unsigned byte, or normalized unsigned
short
github-merge-queue bot pushed a commit that referenced this issue Aug 28, 2023
# Objective

- Meshes with a higher number of joints than `MAX_JOINTS` are crashing
- Fixes partly #9021 (doesn't crash anymore, but the mesh is not
correctly displayed)

## Solution

- Only take up to `MAX_JOINTS` joints when extending the buffer
robtfm pushed a commit to robtfm/bevy that referenced this issue Sep 1, 2023
…engine#9338)

# Objective

- Fixes part of  bevyengine#9021 

## Solution

- Joint mesh are in format `Unorm8x4` in some gltf file, but Bevy
expects a `Float32x4`. Converts them. Also converts `Unorm16x4`
- According to gltf spec:
https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
> WEIGHTS_n: float, or normalized unsigned byte, or normalized unsigned
short
robtfm pushed a commit to robtfm/bevy that referenced this issue Sep 1, 2023
# Objective

- Meshes with a higher number of joints than `MAX_JOINTS` are crashing
- Fixes partly bevyengine#9021 (doesn't crash anymore, but the mesh is not
correctly displayed)

## Solution

- Only take up to `MAX_JOINTS` joints when extending the buffer
vprime pushed a commit to vprime/bevy that referenced this issue Sep 22, 2023
…engine#9338)

# Objective

- Fixes part of  bevyengine#9021

## Solution

- Joint mesh are in format `Unorm8x4` in some gltf file, but Bevy
expects a `Float32x4`. Converts them. Also converts `Unorm16x4`
- According to gltf spec:
https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
> WEIGHTS_n: float, or normalized unsigned byte, or normalized unsigned
short

(cherry picked from commit 3aad5c6)
vprime pushed a commit to vprime/bevy that referenced this issue Sep 22, 2023
# Objective

- Meshes with a higher number of joints than `MAX_JOINTS` are crashing
- Fixes partly bevyengine#9021 (doesn't crash anymore, but the mesh is not
correctly displayed)

## Solution

- Only take up to `MAX_JOINTS` joints when extending the buffer

(cherry picked from commit b28f633)
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this issue Jan 9, 2024
# Objective

- Meshes with a higher number of joints than `MAX_JOINTS` are crashing
- Fixes partly bevyengine#9021 (doesn't crash anymore, but the mesh is not
correctly displayed)

## Solution

- Only take up to `MAX_JOINTS` joints when extending the buffer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior C-Usability A simple quality-of-life change that makes Bevy easier to use P-Crash A sudden unexpected crash
Projects
None yet
Development

No branches or pull requests

4 participants