Skip to content

Commit

Permalink
Fix wireframe for skinned/morphed meshes (#9734)
Browse files Browse the repository at this point in the history
# Objective

- Fixes #6662 
- Wireframe crash for skinned meshes:
```
wgpu error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `opaque_mesh_pipeline`
    Error matching ShaderStages(VERTEX) shader requirements against the pipeline
    Location[4] Uint32x4 interpolated as Some(Flat) with sampling None is not provided by the previous stage outputs
    Input is not provided by the earlier stage in the pipeline
```
- Wireframe crash for morphed meshes:
```
wgpu error: Validation Error

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

## Solution


- Fix the locations for skinned meshes in the wireframe shader
- Add the morph key to the wireframe specialisation key
- Morph the vertex in the wireframe shader


https://github.com/bevyengine/bevy/assets/8672791/ce0a9584-bd28-4d74-9c3f-256602e6fac5
  • Loading branch information
mockersf authored Sep 11, 2023
1 parent 9fafceb commit ae6bc08
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
33 changes: 30 additions & 3 deletions crates/bevy_pbr/src/render/wireframe.wgsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import bevy_pbr::mesh_bindings mesh
#import bevy_pbr::mesh_functions get_model_matrix, mesh_position_local_to_clip
#import bevy_pbr::morph

#ifdef SKINNED
#import bevy_pbr::skinning
Expand All @@ -9,17 +10,43 @@ struct Vertex {
@builtin(instance_index) instance_index: u32,
@location(0) position: vec3<f32>,
#ifdef SKINNED
@location(4) joint_indexes: vec4<u32>,
@location(5) joint_weights: vec4<f32>,
@location(5) joint_indexes: vec4<u32>,
@location(6) joint_weights: vec4<f32>,
#endif
#ifdef MORPH_TARGETS
@builtin(vertex_index) index: u32,
#endif
};

struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
};


#ifdef MORPH_TARGETS
fn morph_vertex(vertex_in: Vertex) -> Vertex {
var vertex = vertex_in;
let weight_count = bevy_pbr::morph::layer_count();
for (var i: u32 = 0u; i < weight_count; i ++) {
let weight = bevy_pbr::morph::weight_at(i);
if weight == 0.0 {
continue;
}
vertex.position += weight * bevy_pbr::morph::morph(vertex.index, bevy_pbr::morph::position_offset, i);
}
return vertex;
}
#endif

@vertex
fn vertex(vertex: Vertex) -> VertexOutput {
fn vertex(vertex_no_morph: Vertex) -> VertexOutput {

#ifdef MORPH_TARGETS
var vertex = morph_vertex(vertex_no_morph);
#else
var vertex = vertex_no_morph;
#endif

#ifdef SKINNED
let model = bevy_pbr::skinning::skin_model(vertex.joint_indexes, vertex.joint_weights);
#else
Expand Down
5 changes: 4 additions & 1 deletion crates/bevy_pbr/src/wireframe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,11 @@ fn queue_wireframes(
let add_render_phase =
|(entity, mesh_handle, mesh_transforms): (Entity, &Handle<Mesh>, &MeshTransforms)| {
if let Some(mesh) = render_meshes.get(mesh_handle) {
let key = view_key
let mut key = view_key
| MeshPipelineKey::from_primitive_topology(mesh.primitive_topology);
if mesh.morph_targets.is_some() {
key |= MeshPipelineKey::MORPH_TARGETS;
}
let pipeline_id = pipelines.specialize(
&pipeline_cache,
&wireframe_pipeline,
Expand Down

0 comments on commit ae6bc08

Please sign in to comment.