mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 15:14:50 +00:00
Fix custom mesh pipelines (#3381)
# Objective Fixes #3379 ## Solution The custom mesh pipelines needed to be specialized on each mesh's primitive topology, as done in `queue_meshes()` Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
46c1480f42
commit
c79ec9cad6
3 changed files with 55 additions and 38 deletions
|
@ -4,10 +4,10 @@ use bevy_app::Plugin;
|
||||||
use bevy_asset::{Assets, Handle, HandleUntyped};
|
use bevy_asset::{Assets, Handle, HandleUntyped};
|
||||||
use bevy_core_pipeline::Opaque3d;
|
use bevy_core_pipeline::Opaque3d;
|
||||||
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
|
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
|
||||||
use bevy_reflect::Reflect;
|
use bevy_reflect::{Reflect, TypeUuid};
|
||||||
use bevy_reflect::TypeUuid;
|
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
|
render_asset::RenderAssets,
|
||||||
render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline},
|
render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline},
|
||||||
render_resource::{RenderPipelineCache, Shader, SpecializedPipeline, SpecializedPipelines},
|
render_resource::{RenderPipelineCache, Shader, SpecializedPipeline, SpecializedPipelines},
|
||||||
view::{ExtractedView, Msaa},
|
view::{ExtractedView, Msaa},
|
||||||
|
@ -93,14 +93,15 @@ impl SpecializedPipeline for WireframePipeline {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn queue_wireframes(
|
fn queue_wireframes(
|
||||||
opaque_3d_draw_functions: Res<DrawFunctions<Opaque3d>>,
|
opaque_3d_draw_functions: Res<DrawFunctions<Opaque3d>>,
|
||||||
|
render_meshes: Res<RenderAssets<Mesh>>,
|
||||||
wireframe_config: Res<WireframeConfig>,
|
wireframe_config: Res<WireframeConfig>,
|
||||||
wireframe_pipeline: Res<WireframePipeline>,
|
wireframe_pipeline: Res<WireframePipeline>,
|
||||||
mut pipeline_cache: ResMut<RenderPipelineCache>,
|
mut pipeline_cache: ResMut<RenderPipelineCache>,
|
||||||
mut specialized_pipelines: ResMut<SpecializedPipelines<WireframePipeline>>,
|
mut specialized_pipelines: ResMut<SpecializedPipelines<WireframePipeline>>,
|
||||||
msaa: Res<Msaa>,
|
msaa: Res<Msaa>,
|
||||||
mut material_meshes: QuerySet<(
|
mut material_meshes: QuerySet<(
|
||||||
QueryState<(Entity, &MeshUniform), With<Handle<Mesh>>>,
|
QueryState<(Entity, &Handle<Mesh>, &MeshUniform)>,
|
||||||
QueryState<(Entity, &MeshUniform), (With<Handle<Mesh>>, With<Wireframe>)>,
|
QueryState<(Entity, &Handle<Mesh>, &MeshUniform), With<Wireframe>>,
|
||||||
)>,
|
)>,
|
||||||
mut views: Query<(&ExtractedView, &mut RenderPhase<Opaque3d>)>,
|
mut views: Query<(&ExtractedView, &mut RenderPhase<Opaque3d>)>,
|
||||||
) {
|
) {
|
||||||
|
@ -113,18 +114,23 @@ fn queue_wireframes(
|
||||||
let view_matrix = view.transform.compute_matrix();
|
let view_matrix = view.transform.compute_matrix();
|
||||||
let view_row_2 = view_matrix.row(2);
|
let view_row_2 = view_matrix.row(2);
|
||||||
|
|
||||||
let add_render_phase = |(entity, mesh_uniform): (Entity, &MeshUniform)| {
|
let add_render_phase =
|
||||||
transparent_phase.add(Opaque3d {
|
|(entity, mesh_handle, mesh_uniform): (Entity, &Handle<Mesh>, &MeshUniform)| {
|
||||||
entity,
|
if let Some(mesh) = render_meshes.get(mesh_handle) {
|
||||||
pipeline: specialized_pipelines.specialize(
|
let key =
|
||||||
&mut pipeline_cache,
|
key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||||
&wireframe_pipeline,
|
transparent_phase.add(Opaque3d {
|
||||||
key,
|
entity,
|
||||||
),
|
pipeline: specialized_pipelines.specialize(
|
||||||
draw_function: draw_custom,
|
&mut pipeline_cache,
|
||||||
distance: view_row_2.dot(mesh_uniform.transform.col(3)),
|
&wireframe_pipeline,
|
||||||
});
|
key,
|
||||||
};
|
),
|
||||||
|
draw_function: draw_custom,
|
||||||
|
distance: view_row_2.dot(mesh_uniform.transform.col(3)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if wireframe_config.global {
|
if wireframe_config.global {
|
||||||
material_meshes.q0().iter().for_each(add_render_phase);
|
material_meshes.q0().iter().for_each(add_render_phase);
|
||||||
|
|
|
@ -6,6 +6,7 @@ use bevy::{
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::{
|
render::{
|
||||||
|
render_asset::RenderAssets,
|
||||||
render_component::{ExtractComponent, ExtractComponentPlugin},
|
render_component::{ExtractComponent, ExtractComponentPlugin},
|
||||||
render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline},
|
render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
|
@ -126,13 +127,15 @@ type DrawIsRed = (
|
||||||
DrawMesh,
|
DrawMesh,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn queue_custom(
|
fn queue_custom(
|
||||||
transparent_3d_draw_functions: Res<DrawFunctions<Transparent3d>>,
|
transparent_3d_draw_functions: Res<DrawFunctions<Transparent3d>>,
|
||||||
|
render_meshes: Res<RenderAssets<Mesh>>,
|
||||||
custom_pipeline: Res<IsRedPipeline>,
|
custom_pipeline: Res<IsRedPipeline>,
|
||||||
msaa: Res<Msaa>,
|
msaa: Res<Msaa>,
|
||||||
mut pipelines: ResMut<SpecializedPipelines<IsRedPipeline>>,
|
mut pipelines: ResMut<SpecializedPipelines<IsRedPipeline>>,
|
||||||
mut pipeline_cache: ResMut<RenderPipelineCache>,
|
mut pipeline_cache: ResMut<RenderPipelineCache>,
|
||||||
material_meshes: Query<(Entity, &MeshUniform, &IsRed), With<Handle<Mesh>>>,
|
material_meshes: Query<(Entity, &Handle<Mesh>, &MeshUniform, &IsRed)>,
|
||||||
mut views: Query<(&ExtractedView, &mut RenderPhase<Transparent3d>)>,
|
mut views: Query<(&ExtractedView, &mut RenderPhase<Transparent3d>)>,
|
||||||
) {
|
) {
|
||||||
let draw_custom = transparent_3d_draw_functions
|
let draw_custom = transparent_3d_draw_functions
|
||||||
|
@ -143,15 +146,18 @@ fn queue_custom(
|
||||||
for (view, mut transparent_phase) in views.iter_mut() {
|
for (view, mut transparent_phase) in views.iter_mut() {
|
||||||
let view_matrix = view.transform.compute_matrix();
|
let view_matrix = view.transform.compute_matrix();
|
||||||
let view_row_2 = view_matrix.row(2);
|
let view_row_2 = view_matrix.row(2);
|
||||||
for (entity, mesh_uniform, is_red) in material_meshes.iter() {
|
for (entity, mesh_handle, mesh_uniform, is_red) in material_meshes.iter() {
|
||||||
let pipeline =
|
if let Some(mesh) = render_meshes.get(mesh_handle) {
|
||||||
pipelines.specialize(&mut pipeline_cache, &custom_pipeline, (*is_red, key));
|
let key = key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||||
transparent_phase.add(Transparent3d {
|
let pipeline =
|
||||||
entity,
|
pipelines.specialize(&mut pipeline_cache, &custom_pipeline, (*is_red, key));
|
||||||
pipeline,
|
transparent_phase.add(Transparent3d {
|
||||||
draw_function: draw_custom,
|
entity,
|
||||||
distance: view_row_2.dot(mesh_uniform.transform.col(3)),
|
pipeline,
|
||||||
});
|
draw_function: draw_custom,
|
||||||
|
distance: view_row_2.dot(mesh_uniform.transform.col(3)),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,11 +171,12 @@ impl FromWorld for CustomPipeline {
|
||||||
pub fn queue_custom(
|
pub fn queue_custom(
|
||||||
transparent_3d_draw_functions: Res<DrawFunctions<Transparent3d>>,
|
transparent_3d_draw_functions: Res<DrawFunctions<Transparent3d>>,
|
||||||
materials: Res<RenderAssets<CustomMaterial>>,
|
materials: Res<RenderAssets<CustomMaterial>>,
|
||||||
|
render_meshes: Res<RenderAssets<Mesh>>,
|
||||||
custom_pipeline: Res<CustomPipeline>,
|
custom_pipeline: Res<CustomPipeline>,
|
||||||
mut pipeline_cache: ResMut<RenderPipelineCache>,
|
mut pipeline_cache: ResMut<RenderPipelineCache>,
|
||||||
mut specialized_pipelines: ResMut<SpecializedPipelines<CustomPipeline>>,
|
mut specialized_pipelines: ResMut<SpecializedPipelines<CustomPipeline>>,
|
||||||
msaa: Res<Msaa>,
|
msaa: Res<Msaa>,
|
||||||
material_meshes: Query<(Entity, &Handle<CustomMaterial>, &MeshUniform), With<Handle<Mesh>>>,
|
material_meshes: Query<(Entity, &Handle<CustomMaterial>, &Handle<Mesh>, &MeshUniform)>,
|
||||||
mut views: Query<(&ExtractedView, &mut RenderPhase<Transparent3d>)>,
|
mut views: Query<(&ExtractedView, &mut RenderPhase<Transparent3d>)>,
|
||||||
) {
|
) {
|
||||||
let draw_custom = transparent_3d_draw_functions
|
let draw_custom = transparent_3d_draw_functions
|
||||||
|
@ -186,18 +187,22 @@ pub fn queue_custom(
|
||||||
for (view, mut transparent_phase) in views.iter_mut() {
|
for (view, mut transparent_phase) in views.iter_mut() {
|
||||||
let view_matrix = view.transform.compute_matrix();
|
let view_matrix = view.transform.compute_matrix();
|
||||||
let view_row_2 = view_matrix.row(2);
|
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) {
|
if materials.contains_key(material_handle) {
|
||||||
transparent_phase.add(Transparent3d {
|
if let Some(mesh) = render_meshes.get(mesh_handle) {
|
||||||
entity,
|
let key =
|
||||||
pipeline: specialized_pipelines.specialize(
|
key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||||
&mut pipeline_cache,
|
transparent_phase.add(Transparent3d {
|
||||||
&custom_pipeline,
|
entity,
|
||||||
key,
|
pipeline: specialized_pipelines.specialize(
|
||||||
),
|
&mut pipeline_cache,
|
||||||
draw_function: draw_custom,
|
&custom_pipeline,
|
||||||
distance: view_row_2.dot(mesh_uniform.transform.col(3)),
|
key,
|
||||||
});
|
),
|
||||||
|
draw_function: draw_custom,
|
||||||
|
distance: view_row_2.dot(mesh_uniform.transform.col(3)),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue