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:
Kurt Kühnert 2023-02-13 19:33:51 +00:00
parent bf514ff12c
commit d7d983be60

View File

@ -418,14 +418,15 @@ 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),
render_materials.get(material_handle),
) {
let mut mesh_key = let mut mesh_key =
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology) MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
| view_key; | view_key;
let alpha_mode = material.properties.alpha_mode; let alpha_mode = material.properties.alpha_mode;
if let AlphaMode::Blend | AlphaMode::Premultiplied | AlphaMode::Add = if let AlphaMode::Blend | AlphaMode::Premultiplied | AlphaMode::Add = alpha_mode
alpha_mode
{ {
// Blend, Premultiplied and Add all share the same pipeline key // Blend, Premultiplied and Add all share the same pipeline key
// They're made distinct in the PBR shader, via `premultiply_alpha()` // They're made distinct in the PBR shader, via `premultiply_alpha()`
@ -486,7 +487,6 @@ pub fn queue_material_meshes<M: Material>(
} }
} }
} }
}
} }
/// Common [`Material`] properties, calculated for a specific material instance. /// Common [`Material`] properties, calculated for a specific material instance.
@ -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>>,