Skip to content

Commit d7d983b

Browse files
committed
Reusable Material Pipeline (#7548)
# Objective - rebased version of #6155 The `MaterialPipeline` cannot be integrated into other pipelines like the `MeshPipeline`. ## Solution Implement `Clone` for `MaterialPipeline`. Expose systems and resources part of the `MaterialPlugin` to allow custom assembly - especially combining existing systems and resources with a custom `queue_material_meshes` system. # Changelog ## Added - Clone impl for MaterialPipeline ## Changed - ExtractedMaterials, extract_materials and prepare_materials are now public
1 parent bf514ff commit d7d983b

File tree

1 file changed

+65
-65
lines changed

1 file changed

+65
-65
lines changed

crates/bevy_pbr/src/material.rs

Lines changed: 65 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -418,69 +418,69 @@ pub fn queue_material_meshes<M: Material>(
418418
if let Ok((material_handle, mesh_handle, mesh_uniform)) =
419419
material_meshes.get(*visible_entity)
420420
{
421-
if let Some(material) = render_materials.get(material_handle) {
422-
if let Some(mesh) = render_meshes.get(mesh_handle) {
423-
let mut mesh_key =
424-
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
425-
| view_key;
426-
let alpha_mode = material.properties.alpha_mode;
427-
if let AlphaMode::Blend | AlphaMode::Premultiplied | AlphaMode::Add =
428-
alpha_mode
429-
{
430-
// Blend, Premultiplied and Add all share the same pipeline key
431-
// They're made distinct in the PBR shader, via `premultiply_alpha()`
432-
mesh_key |= MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA;
433-
} else if let AlphaMode::Multiply = alpha_mode {
434-
mesh_key |= MeshPipelineKey::BLEND_MULTIPLY;
435-
}
421+
if let (Some(mesh), Some(material)) = (
422+
render_meshes.get(mesh_handle),
423+
render_materials.get(material_handle),
424+
) {
425+
let mut mesh_key =
426+
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
427+
| view_key;
428+
let alpha_mode = material.properties.alpha_mode;
429+
if let AlphaMode::Blend | AlphaMode::Premultiplied | AlphaMode::Add = alpha_mode
430+
{
431+
// Blend, Premultiplied and Add all share the same pipeline key
432+
// They're made distinct in the PBR shader, via `premultiply_alpha()`
433+
mesh_key |= MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA;
434+
} else if let AlphaMode::Multiply = alpha_mode {
435+
mesh_key |= MeshPipelineKey::BLEND_MULTIPLY;
436+
}
436437

437-
let pipeline_id = pipelines.specialize(
438-
&pipeline_cache,
439-
&material_pipeline,
440-
MaterialPipelineKey {
441-
mesh_key,
442-
bind_group_data: material.key.clone(),
443-
},
444-
&mesh.layout,
445-
);
446-
let pipeline_id = match pipeline_id {
447-
Ok(id) => id,
448-
Err(err) => {
449-
error!("{}", err);
450-
continue;
451-
}
452-
};
453-
454-
let distance = rangefinder.distance(&mesh_uniform.transform)
455-
+ material.properties.depth_bias;
456-
match alpha_mode {
457-
AlphaMode::Opaque => {
458-
opaque_phase.add(Opaque3d {
459-
entity: *visible_entity,
460-
draw_function: draw_opaque_pbr,
461-
pipeline: pipeline_id,
462-
distance,
463-
});
464-
}
465-
AlphaMode::Mask(_) => {
466-
alpha_mask_phase.add(AlphaMask3d {
467-
entity: *visible_entity,
468-
draw_function: draw_alpha_mask_pbr,
469-
pipeline: pipeline_id,
470-
distance,
471-
});
472-
}
473-
AlphaMode::Blend
474-
| AlphaMode::Premultiplied
475-
| AlphaMode::Add
476-
| AlphaMode::Multiply => {
477-
transparent_phase.add(Transparent3d {
478-
entity: *visible_entity,
479-
draw_function: draw_transparent_pbr,
480-
pipeline: pipeline_id,
481-
distance,
482-
});
483-
}
438+
let pipeline_id = pipelines.specialize(
439+
&pipeline_cache,
440+
&material_pipeline,
441+
MaterialPipelineKey {
442+
mesh_key,
443+
bind_group_data: material.key.clone(),
444+
},
445+
&mesh.layout,
446+
);
447+
let pipeline_id = match pipeline_id {
448+
Ok(id) => id,
449+
Err(err) => {
450+
error!("{}", err);
451+
continue;
452+
}
453+
};
454+
455+
let distance = rangefinder.distance(&mesh_uniform.transform)
456+
+ material.properties.depth_bias;
457+
match alpha_mode {
458+
AlphaMode::Opaque => {
459+
opaque_phase.add(Opaque3d {
460+
entity: *visible_entity,
461+
draw_function: draw_opaque_pbr,
462+
pipeline: pipeline_id,
463+
distance,
464+
});
465+
}
466+
AlphaMode::Mask(_) => {
467+
alpha_mask_phase.add(AlphaMask3d {
468+
entity: *visible_entity,
469+
draw_function: draw_alpha_mask_pbr,
470+
pipeline: pipeline_id,
471+
distance,
472+
});
473+
}
474+
AlphaMode::Blend
475+
| AlphaMode::Premultiplied
476+
| AlphaMode::Add
477+
| AlphaMode::Multiply => {
478+
transparent_phase.add(Transparent3d {
479+
entity: *visible_entity,
480+
draw_function: draw_transparent_pbr,
481+
pipeline: pipeline_id,
482+
distance,
483+
});
484484
}
485485
}
486486
}
@@ -507,7 +507,7 @@ pub struct PreparedMaterial<T: Material> {
507507
}
508508

509509
#[derive(Resource)]
510-
struct ExtractedMaterials<M: Material> {
510+
pub struct ExtractedMaterials<M: Material> {
511511
extracted: Vec<(Handle<M>, M)>,
512512
removed: Vec<Handle<M>>,
513513
}
@@ -533,7 +533,7 @@ impl<T: Material> Default for RenderMaterials<T> {
533533

534534
/// This system extracts all created or modified assets of the corresponding [`Material`] type
535535
/// into the "render world".
536-
fn extract_materials<M: Material>(
536+
pub fn extract_materials<M: Material>(
537537
mut commands: Commands,
538538
mut events: Extract<EventReader<AssetEvent<M>>>,
539539
assets: Extract<Res<Assets<M>>>,
@@ -580,7 +580,7 @@ impl<M: Material> Default for PrepareNextFrameMaterials<M> {
580580

581581
/// This system prepares all assets of the corresponding [`Material`] type
582582
/// which where extracted this frame for the GPU.
583-
fn prepare_materials<M: Material>(
583+
pub fn prepare_materials<M: Material>(
584584
mut prepare_next_frame: Local<PrepareNextFrameMaterials<M>>,
585585
mut extracted_assets: ResMut<ExtractedMaterials<M>>,
586586
mut render_materials: ResMut<RenderMaterials<M>>,

0 commit comments

Comments
 (0)