Fix wireframe for skinned/morphed meshes (#9734)

# 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
This commit is contained in:
François 2023-09-11 21:14:15 +02:00 committed by GitHub
parent 9fafceba90
commit ae6bc08a58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 4 deletions

View file

@ -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
@ -9,8 +10,11 @@ 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
};
@ -18,8 +22,31 @@ 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

View file

@ -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,