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
This commit is contained in:
parent
bf514ff12c
commit
d7d983be60
@ -418,69 +418,69 @@ pub fn queue_material_meshes<M: Material>(
|
|||||||
if let Ok((material_handle, mesh_handle, mesh_uniform)) =
|
if let Ok((material_handle, mesh_handle, mesh_uniform)) =
|
||||||
material_meshes.get(*visible_entity)
|
material_meshes.get(*visible_entity)
|
||||||
{
|
{
|
||||||
if let Some(material) = render_materials.get(material_handle) {
|
if let (Some(mesh), Some(material)) = (
|
||||||
if let Some(mesh) = render_meshes.get(mesh_handle) {
|
render_meshes.get(mesh_handle),
|
||||||
let mut mesh_key =
|
render_materials.get(material_handle),
|
||||||
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
|
) {
|
||||||
| view_key;
|
let mut mesh_key =
|
||||||
let alpha_mode = material.properties.alpha_mode;
|
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
|
||||||
if let AlphaMode::Blend | AlphaMode::Premultiplied | AlphaMode::Add =
|
| view_key;
|
||||||
alpha_mode
|
let alpha_mode = material.properties.alpha_mode;
|
||||||
{
|
if let AlphaMode::Blend | AlphaMode::Premultiplied | AlphaMode::Add = alpha_mode
|
||||||
// Blend, Premultiplied and Add all share the same pipeline key
|
{
|
||||||
// They're made distinct in the PBR shader, via `premultiply_alpha()`
|
// Blend, Premultiplied and Add all share the same pipeline key
|
||||||
mesh_key |= MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA;
|
// They're made distinct in the PBR shader, via `premultiply_alpha()`
|
||||||
} else if let AlphaMode::Multiply = alpha_mode {
|
mesh_key |= MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA;
|
||||||
mesh_key |= MeshPipelineKey::BLEND_MULTIPLY;
|
} else if let AlphaMode::Multiply = alpha_mode {
|
||||||
|
mesh_key |= MeshPipelineKey::BLEND_MULTIPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pipeline_id = pipelines.specialize(
|
||||||
|
&pipeline_cache,
|
||||||
|
&material_pipeline,
|
||||||
|
MaterialPipelineKey {
|
||||||
|
mesh_key,
|
||||||
|
bind_group_data: material.key.clone(),
|
||||||
|
},
|
||||||
|
&mesh.layout,
|
||||||
|
);
|
||||||
|
let pipeline_id = match pipeline_id {
|
||||||
|
Ok(id) => id,
|
||||||
|
Err(err) => {
|
||||||
|
error!("{}", err);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let pipeline_id = pipelines.specialize(
|
let distance = rangefinder.distance(&mesh_uniform.transform)
|
||||||
&pipeline_cache,
|
+ material.properties.depth_bias;
|
||||||
&material_pipeline,
|
match alpha_mode {
|
||||||
MaterialPipelineKey {
|
AlphaMode::Opaque => {
|
||||||
mesh_key,
|
opaque_phase.add(Opaque3d {
|
||||||
bind_group_data: material.key.clone(),
|
entity: *visible_entity,
|
||||||
},
|
draw_function: draw_opaque_pbr,
|
||||||
&mesh.layout,
|
pipeline: pipeline_id,
|
||||||
);
|
distance,
|
||||||
let pipeline_id = match pipeline_id {
|
});
|
||||||
Ok(id) => id,
|
}
|
||||||
Err(err) => {
|
AlphaMode::Mask(_) => {
|
||||||
error!("{}", err);
|
alpha_mask_phase.add(AlphaMask3d {
|
||||||
continue;
|
entity: *visible_entity,
|
||||||
}
|
draw_function: draw_alpha_mask_pbr,
|
||||||
};
|
pipeline: pipeline_id,
|
||||||
|
distance,
|
||||||
let distance = rangefinder.distance(&mesh_uniform.transform)
|
});
|
||||||
+ material.properties.depth_bias;
|
}
|
||||||
match alpha_mode {
|
AlphaMode::Blend
|
||||||
AlphaMode::Opaque => {
|
| AlphaMode::Premultiplied
|
||||||
opaque_phase.add(Opaque3d {
|
| AlphaMode::Add
|
||||||
entity: *visible_entity,
|
| AlphaMode::Multiply => {
|
||||||
draw_function: draw_opaque_pbr,
|
transparent_phase.add(Transparent3d {
|
||||||
pipeline: pipeline_id,
|
entity: *visible_entity,
|
||||||
distance,
|
draw_function: draw_transparent_pbr,
|
||||||
});
|
pipeline: pipeline_id,
|
||||||
}
|
distance,
|
||||||
AlphaMode::Mask(_) => {
|
});
|
||||||
alpha_mask_phase.add(AlphaMask3d {
|
|
||||||
entity: *visible_entity,
|
|
||||||
draw_function: draw_alpha_mask_pbr,
|
|
||||||
pipeline: pipeline_id,
|
|
||||||
distance,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
AlphaMode::Blend
|
|
||||||
| AlphaMode::Premultiplied
|
|
||||||
| AlphaMode::Add
|
|
||||||
| AlphaMode::Multiply => {
|
|
||||||
transparent_phase.add(Transparent3d {
|
|
||||||
entity: *visible_entity,
|
|
||||||
draw_function: draw_transparent_pbr,
|
|
||||||
pipeline: pipeline_id,
|
|
||||||
distance,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -507,7 +507,7 @@ pub struct PreparedMaterial<T: Material> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct ExtractedMaterials<M: Material> {
|
pub struct ExtractedMaterials<M: Material> {
|
||||||
extracted: Vec<(Handle<M>, M)>,
|
extracted: Vec<(Handle<M>, M)>,
|
||||||
removed: Vec<Handle<M>>,
|
removed: Vec<Handle<M>>,
|
||||||
}
|
}
|
||||||
@ -533,7 +533,7 @@ impl<T: Material> Default for RenderMaterials<T> {
|
|||||||
|
|
||||||
/// This system extracts all created or modified assets of the corresponding [`Material`] type
|
/// This system extracts all created or modified assets of the corresponding [`Material`] type
|
||||||
/// into the "render world".
|
/// into the "render world".
|
||||||
fn extract_materials<M: Material>(
|
pub fn extract_materials<M: Material>(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut events: Extract<EventReader<AssetEvent<M>>>,
|
mut events: Extract<EventReader<AssetEvent<M>>>,
|
||||||
assets: Extract<Res<Assets<M>>>,
|
assets: Extract<Res<Assets<M>>>,
|
||||||
@ -580,7 +580,7 @@ impl<M: Material> Default for PrepareNextFrameMaterials<M> {
|
|||||||
|
|
||||||
/// This system prepares all assets of the corresponding [`Material`] type
|
/// This system prepares all assets of the corresponding [`Material`] type
|
||||||
/// which where extracted this frame for the GPU.
|
/// which where extracted this frame for the GPU.
|
||||||
fn prepare_materials<M: Material>(
|
pub fn prepare_materials<M: Material>(
|
||||||
mut prepare_next_frame: Local<PrepareNextFrameMaterials<M>>,
|
mut prepare_next_frame: Local<PrepareNextFrameMaterials<M>>,
|
||||||
mut extracted_assets: ResMut<ExtractedMaterials<M>>,
|
mut extracted_assets: ResMut<ExtractedMaterials<M>>,
|
||||||
mut render_materials: ResMut<RenderMaterials<M>>,
|
mut render_materials: ResMut<RenderMaterials<M>>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user