diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 1241393a41e44..2069a54b16e44 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -4,10 +4,10 @@ use bevy_app::Plugin; use bevy_asset::{Assets, Handle, HandleUntyped}; use bevy_core_pipeline::Opaque3d; use bevy_ecs::{prelude::*, reflect::ReflectComponent}; -use bevy_reflect::Reflect; -use bevy_reflect::TypeUuid; +use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::{ mesh::Mesh, + render_asset::RenderAssets, render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline}, render_resource::{RenderPipelineCache, Shader, SpecializedPipeline, SpecializedPipelines}, view::{ExtractedView, Msaa}, @@ -93,14 +93,15 @@ impl SpecializedPipeline for WireframePipeline { #[allow(clippy::too_many_arguments)] fn queue_wireframes( opaque_3d_draw_functions: Res>, + render_meshes: Res>, wireframe_config: Res, wireframe_pipeline: Res, mut pipeline_cache: ResMut, mut specialized_pipelines: ResMut>, msaa: Res, mut material_meshes: QuerySet<( - QueryState<(Entity, &MeshUniform), With>>, - QueryState<(Entity, &MeshUniform), (With>, With)>, + QueryState<(Entity, &Handle, &MeshUniform)>, + QueryState<(Entity, &Handle, &MeshUniform), With>, )>, mut views: Query<(&ExtractedView, &mut RenderPhase)>, ) { @@ -113,18 +114,23 @@ fn queue_wireframes( let view_matrix = view.transform.compute_matrix(); let view_row_2 = view_matrix.row(2); - let add_render_phase = |(entity, mesh_uniform): (Entity, &MeshUniform)| { - transparent_phase.add(Opaque3d { - entity, - pipeline: specialized_pipelines.specialize( - &mut pipeline_cache, - &wireframe_pipeline, - key, - ), - draw_function: draw_custom, - distance: view_row_2.dot(mesh_uniform.transform.col(3)), - }); - }; + let add_render_phase = + |(entity, mesh_handle, mesh_uniform): (Entity, &Handle, &MeshUniform)| { + if let Some(mesh) = render_meshes.get(mesh_handle) { + let key = + key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); + transparent_phase.add(Opaque3d { + entity, + pipeline: specialized_pipelines.specialize( + &mut pipeline_cache, + &wireframe_pipeline, + key, + ), + draw_function: draw_custom, + distance: view_row_2.dot(mesh_uniform.transform.col(3)), + }); + } + }; if wireframe_config.global { material_meshes.q0().iter().for_each(add_render_phase); diff --git a/examples/shader/shader_defs.rs b/examples/shader/shader_defs.rs index 6dc4f9d2244bf..18014e32192d9 100644 --- a/examples/shader/shader_defs.rs +++ b/examples/shader/shader_defs.rs @@ -6,6 +6,7 @@ use bevy::{ }, prelude::*, render::{ + render_asset::RenderAssets, render_component::{ExtractComponent, ExtractComponentPlugin}, render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline}, render_resource::{ @@ -126,13 +127,15 @@ type DrawIsRed = ( DrawMesh, ); +#[allow(clippy::too_many_arguments)] fn queue_custom( transparent_3d_draw_functions: Res>, + render_meshes: Res>, custom_pipeline: Res, msaa: Res, mut pipelines: ResMut>, mut pipeline_cache: ResMut, - material_meshes: Query<(Entity, &MeshUniform, &IsRed), With>>, + material_meshes: Query<(Entity, &Handle, &MeshUniform, &IsRed)>, mut views: Query<(&ExtractedView, &mut RenderPhase)>, ) { let draw_custom = transparent_3d_draw_functions @@ -143,15 +146,18 @@ fn queue_custom( for (view, mut transparent_phase) in views.iter_mut() { let view_matrix = view.transform.compute_matrix(); let view_row_2 = view_matrix.row(2); - for (entity, mesh_uniform, is_red) in material_meshes.iter() { - let pipeline = - pipelines.specialize(&mut pipeline_cache, &custom_pipeline, (*is_red, key)); - transparent_phase.add(Transparent3d { - entity, - pipeline, - draw_function: draw_custom, - distance: view_row_2.dot(mesh_uniform.transform.col(3)), - }); + for (entity, mesh_handle, mesh_uniform, is_red) in material_meshes.iter() { + if let Some(mesh) = render_meshes.get(mesh_handle) { + let key = key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); + let pipeline = + pipelines.specialize(&mut pipeline_cache, &custom_pipeline, (*is_red, key)); + transparent_phase.add(Transparent3d { + entity, + pipeline, + draw_function: draw_custom, + distance: view_row_2.dot(mesh_uniform.transform.col(3)), + }); + } } } } diff --git a/examples/shader/shader_material.rs b/examples/shader/shader_material.rs index cf08b99fd32ab..e7c4737023a71 100644 --- a/examples/shader/shader_material.rs +++ b/examples/shader/shader_material.rs @@ -171,11 +171,12 @@ impl FromWorld for CustomPipeline { pub fn queue_custom( transparent_3d_draw_functions: Res>, materials: Res>, + render_meshes: Res>, custom_pipeline: Res, mut pipeline_cache: ResMut, mut specialized_pipelines: ResMut>, msaa: Res, - material_meshes: Query<(Entity, &Handle, &MeshUniform), With>>, + material_meshes: Query<(Entity, &Handle, &Handle, &MeshUniform)>, mut views: Query<(&ExtractedView, &mut RenderPhase)>, ) { let draw_custom = transparent_3d_draw_functions @@ -186,18 +187,22 @@ pub fn queue_custom( for (view, mut transparent_phase) in views.iter_mut() { let view_matrix = view.transform.compute_matrix(); let view_row_2 = view_matrix.row(2); - for (entity, material_handle, mesh_uniform) in material_meshes.iter() { + for (entity, material_handle, mesh_handle, mesh_uniform) in material_meshes.iter() { if materials.contains_key(material_handle) { - transparent_phase.add(Transparent3d { - entity, - pipeline: specialized_pipelines.specialize( - &mut pipeline_cache, - &custom_pipeline, - key, - ), - draw_function: draw_custom, - distance: view_row_2.dot(mesh_uniform.transform.col(3)), - }); + if let Some(mesh) = render_meshes.get(mesh_handle) { + let key = + key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); + transparent_phase.add(Transparent3d { + entity, + pipeline: specialized_pipelines.specialize( + &mut pipeline_cache, + &custom_pipeline, + key, + ), + draw_function: draw_custom, + distance: view_row_2.dot(mesh_uniform.transform.col(3)), + }); + } } } }