Revert default mesh materials (#15930)

# Objective

Closes #15799.

Many rendering people and maintainers are in favor of reverting default
mesh materials added in #15524, especially as the migration to required
component is already large and heavily breaking.

## Solution

Revert default mesh materials, and adjust docs accordingly.

- Remove `extract_default_materials`
- Remove `clear_material_instances`, and move the logic back into
`extract_mesh_materials`
- Remove `HasMaterial2d` and `HasMaterial3d`
- Change default material handles back to pink instead of white
- 2D uses `Color::srgb(1.0, 0.0, 1.0)`, while 3D uses `Color::srgb(1.0,
0.0, 0.5)`. Not sure if this is intended.

There is now no indication at all about missing materials for `Mesh2d`
and `Mesh3d`. Having a mesh without a material renders nothing.

## Testing

I ran `2d_shapes`, `mesh2d_manual`, and `3d_shapes`, with and without
mesh material components.
This commit is contained in:
Joona Aalto 2024-10-15 22:47:40 +03:00 committed by GitHub
parent 424e563184
commit c1a4b82762
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 18 additions and 178 deletions

View file

@ -422,13 +422,13 @@ impl Plugin for PbrPlugin {
app.add_plugins(DeferredPbrLightingPlugin);
}
// Initialize the default material.
// Initialize the default material handle.
app.world_mut()
.resource_mut::<Assets<StandardMaterial>>()
.insert(
&Handle::<StandardMaterial>::default(),
StandardMaterial {
base_color: Color::WHITE,
base_color: Color::srgb(1.0, 0.0, 0.5),
..Default::default()
},
);
@ -439,14 +439,7 @@ impl Plugin for PbrPlugin {
// Extract the required data from the main world
render_app
.add_systems(
ExtractSchedule,
(
extract_clusters,
extract_lights,
extract_default_materials.after(clear_material_instances::<StandardMaterial>),
),
)
.add_systems(ExtractSchedule, (extract_clusters, extract_lights))
.add_systems(
Render,
(

View file

@ -270,7 +270,6 @@ where
fn build(&self, app: &mut App) {
app.init_asset::<M>()
.register_type::<MeshMaterial3d<M>>()
.register_type::<HasMaterial3d>()
.add_plugins(RenderAssetPlugin::<PreparedMaterial<M>>::default());
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
@ -283,10 +282,7 @@ where
.add_render_command::<Opaque3d, DrawMaterial<M>>()
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
.init_resource::<SpecializedMeshPipelines<MaterialPipeline<M>>>()
.add_systems(
ExtractSchedule,
(clear_material_instances::<M>, extract_mesh_materials::<M>).chain(),
)
.add_systems(ExtractSchedule, extract_mesh_materials::<M>)
.add_systems(
Render,
queue_material_meshes::<M>
@ -550,16 +546,12 @@ pub const fn screen_space_specular_transmission_pipeline_key(
}
}
pub(super) fn clear_material_instances<M: Material>(
mut material_instances: ResMut<RenderMaterialInstances<M>>,
) {
material_instances.clear();
}
fn extract_mesh_materials<M: Material>(
mut material_instances: ResMut<RenderMaterialInstances<M>>,
query: Extract<Query<(Entity, &ViewVisibility, &MeshMaterial3d<M>)>>,
) {
material_instances.clear();
for (entity, view_visibility, material) in &query {
if view_visibility.get() {
material_instances.insert(entity.into(), material.id());
@ -567,18 +559,6 @@ fn extract_mesh_materials<M: Material>(
}
}
/// Extracts default materials for 3D meshes with no [`MeshMaterial3d`].
pub(super) fn extract_default_materials(
mut material_instances: ResMut<RenderMaterialInstances<StandardMaterial>>,
query: Extract<Query<(Entity, &ViewVisibility), (With<Mesh3d>, Without<HasMaterial3d>)>>,
) {
for (entity, view_visibility) in &query {
if view_visibility.get() {
material_instances.insert(entity.into(), AssetId::default());
}
}
}
/// For each view, iterates over all the meshes visible from that view and adds
/// them to [`BinnedRenderPhase`]s or [`SortedRenderPhase`]s as appropriate.
#[allow(clippy::too_many_arguments)]

View file

@ -5,7 +5,7 @@ use bevy_ecs::{component::Component, reflect::ReflectComponent};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use derive_more::derive::From;
/// A [material](Material) for a [`Mesh3d`].
/// A [material](Material) used for rendering a [`Mesh3d`].
///
/// See [`Material`] for general information about 3D materials and how to implement your own materials.
///
@ -36,41 +36,8 @@ use derive_more::derive::From;
/// ));
/// }
/// ```
///
/// ## Default Material
///
/// Meshes without a [`MeshMaterial3d`] are rendered with a default [`StandardMaterial`].
/// This material can be overridden by inserting a custom material for the default asset handle.
///
/// ```
/// # use bevy_pbr::{Material, MeshMaterial3d, StandardMaterial};
/// # use bevy_ecs::prelude::*;
/// # use bevy_render::mesh::{Mesh, Mesh3d};
/// # use bevy_color::Color;
/// # use bevy_asset::{Assets, Handle};
/// # use bevy_math::primitives::Capsule3d;
/// #
/// fn setup(
/// mut commands: Commands,
/// mut meshes: ResMut<Assets<Mesh>>,
/// mut materials: ResMut<Assets<StandardMaterial>>,
/// ) {
/// // Optional: Insert a custom default material.
/// materials.insert(
/// &Handle::<StandardMaterial>::default(),
/// StandardMaterial::from(Color::srgb(1.0, 0.0, 1.0)),
/// );
///
/// // Spawn a capsule with no material.
/// // The mesh will be rendered with the default material.
/// commands.spawn(Mesh3d(meshes.add(Capsule3d::default())));
/// }
/// ```
///
/// [`StandardMaterial`]: crate::StandardMaterial
#[derive(Component, Clone, Debug, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
#[reflect(Component, Default)]
#[require(HasMaterial3d)]
pub struct MeshMaterial3d<M: Material>(pub Handle<M>);
impl<M: Material> Default for MeshMaterial3d<M> {
@ -90,12 +57,3 @@ impl<M: Material> From<&MeshMaterial3d<M>> for AssetId<M> {
material.id()
}
}
/// A component that marks an entity as having a [`MeshMaterial3d`].
/// [`Mesh3d`] entities without this component are rendered with a [default material].
///
/// [`Mesh3d`]: bevy_render::mesh::Mesh3d
/// [default material]: crate::MeshMaterial3d#default-material
#[derive(Component, Clone, Debug, Default, Reflect)]
#[reflect(Component, Default)]
pub struct HasMaterial3d;

View file

@ -6,13 +6,10 @@ use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_transform::components::Transform;
use derive_more::derive::From;
/// A component for rendering 2D meshes, typically with a [`MeshMaterial2d`] using a [`ColorMaterial`].
///
/// Meshes without a [`MeshMaterial2d`] will be rendered with a [default material].
/// A component for 2D meshes. Requires a [`MeshMaterial2d`] to be rendered, commonly using a [`ColorMaterial`].
///
/// [`MeshMaterial2d`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.MeshMaterial2d.html>
/// [`ColorMaterial`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.ColorMaterial.html>
/// [default material]: <https://docs.rs/bevy/latest/bevy/sprite/struct.MeshMaterial2d.html#default-material>
///
/// # Example
///
@ -53,13 +50,10 @@ impl From<&Mesh2d> for AssetId<Mesh> {
}
}
/// A component for rendering 3D meshes, typically with a [`MeshMaterial3d`] using a [`StandardMaterial`].
///
/// Meshes without a [`MeshMaterial3d`] will be rendered with a [default material].
/// A component for 3D meshes. Requires a [`MeshMaterial3d`] to be rendered, commonly using a [`StandardMaterial`].
///
/// [`MeshMaterial3d`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.MeshMaterial3d.html>
/// [`StandardMaterial`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html>
/// [default material]: <https://docs.rs/bevy/latest/bevy/pbr/struct.MeshMaterial3d.html#default-material>
///
/// # Example
///

View file

@ -1,20 +1,15 @@
#![expect(deprecated)]
use crate::{
clear_material_2d_instances, extract_default_materials_2d, AlphaMode2d, Material2d,
Material2dPlugin, MaterialMesh2dBundle,
};
use crate::{AlphaMode2d, Material2d, Material2dPlugin, MaterialMesh2dBundle};
use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Asset, AssetApp, Assets, Handle};
use bevy_color::{Alpha, Color, ColorToComponents, LinearRgba};
use bevy_ecs::schedule::IntoSystemConfigs;
use bevy_math::Vec4;
use bevy_reflect::prelude::*;
use bevy_render::{
render_asset::RenderAssets,
render_resource::*,
texture::{GpuImage, Image},
ExtractSchedule, RenderApp,
};
pub const COLOR_MATERIAL_SHADER_HANDLE: Handle<Shader> =
@ -35,26 +30,16 @@ impl Plugin for ColorMaterialPlugin {
app.add_plugins(Material2dPlugin::<ColorMaterial>::default())
.register_asset_reflect::<ColorMaterial>();
// Initialize the default material.
// Initialize the default material handle.
app.world_mut()
.resource_mut::<Assets<ColorMaterial>>()
.insert(
&Handle::<ColorMaterial>::default(),
ColorMaterial {
color: Color::WHITE,
color: Color::srgb(1.0, 0.0, 1.0),
..Default::default()
},
);
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
// Extract default materials for entities with no material.
render_app.add_systems(
ExtractSchedule,
extract_default_materials_2d.after(clear_material_2d_instances::<ColorMaterial>),
);
}
}

View file

@ -43,8 +43,6 @@ use bevy_utils::tracing::error;
use core::{hash::Hash, marker::PhantomData};
use derive_more::derive::From;
use super::ColorMaterial;
/// Materials are used alongside [`Material2dPlugin`], [`Mesh2d`], and [`MeshMaterial2d`]
/// to spawn entities that are rendered with a specific [`Material2d`] type. They serve as an easy to use high level
/// way to render [`Mesh2d`] entities with custom shader logic.
@ -151,7 +149,7 @@ pub trait Material2d: AsBindGroup + Asset + Clone + Sized {
}
}
/// A [material](Material2d) for a [`Mesh2d`].
/// A [material](Material2d) used for rendering a [`Mesh2d`].
///
/// See [`Material2d`] for general information about 2D materials and how to implement your own materials.
///
@ -179,40 +177,8 @@ pub trait Material2d: AsBindGroup + Asset + Clone + Sized {
/// ```
///
/// [`MeshMaterial2d`]: crate::MeshMaterial2d
/// [`ColorMaterial`]: crate::ColorMaterial
///
/// ## Default Material
///
/// Meshes without a [`MeshMaterial2d`] are rendered with a default [`ColorMaterial`].
/// This material can be overridden by inserting a custom material for the default asset handle.
///
/// ```
/// # use bevy_sprite::ColorMaterial;
/// # use bevy_ecs::prelude::*;
/// # use bevy_render::mesh::{Mesh, Mesh2d};
/// # use bevy_color::Color;
/// # use bevy_asset::{Assets, Handle};
/// # use bevy_math::primitives::Circle;
/// #
/// fn setup(
/// mut commands: Commands,
/// mut meshes: ResMut<Assets<Mesh>>,
/// mut materials: ResMut<Assets<ColorMaterial>>,
/// ) {
/// // Optional: Insert a custom default material.
/// materials.insert(
/// &Handle::<ColorMaterial>::default(),
/// ColorMaterial::from(Color::srgb(1.0, 0.0, 1.0)),
/// );
///
/// // Spawn a circle with no material.
/// // The mesh will be rendered with the default material.
/// commands.spawn(Mesh2d(meshes.add(Circle::new(50.0))));
/// }
/// ```
#[derive(Component, Clone, Debug, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
#[reflect(Component, Default)]
#[require(HasMaterial2d)]
pub struct MeshMaterial2d<M: Material2d>(pub Handle<M>);
impl<M: Material2d> Default for MeshMaterial2d<M> {
@ -233,14 +199,6 @@ impl<M: Material2d> From<&MeshMaterial2d<M>> for AssetId<M> {
}
}
/// A component that marks an entity as having a [`MeshMaterial2d`].
/// [`Mesh2d`] entities without this component are rendered with a [default material].
///
/// [default material]: crate::MeshMaterial2d#default-material
#[derive(Component, Clone, Debug, Default, Reflect)]
#[reflect(Component, Default)]
pub struct HasMaterial2d;
/// Sets how a 2d material's base color alpha channel is used for transparency.
/// Currently, this only works with [`Mesh2d`]. Sprites are always transparent.
///
@ -284,7 +242,6 @@ where
fn build(&self, app: &mut App) {
app.init_asset::<M>()
.register_type::<MeshMaterial2d<M>>()
.register_type::<HasMaterial2d>()
.add_plugins(RenderAssetPlugin::<PreparedMaterial2d<M>>::default());
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
@ -294,14 +251,7 @@ where
.add_render_command::<Transparent2d, DrawMaterial2d<M>>()
.init_resource::<RenderMaterial2dInstances<M>>()
.init_resource::<SpecializedMeshPipelines<Material2dPipeline<M>>>()
.add_systems(
ExtractSchedule,
(
clear_material_2d_instances::<M>,
extract_mesh_materials_2d::<M>,
)
.chain(),
)
.add_systems(ExtractSchedule, extract_mesh_materials_2d::<M>)
.add_systems(
Render,
queue_material2d_meshes::<M>
@ -327,16 +277,12 @@ impl<M: Material2d> Default for RenderMaterial2dInstances<M> {
}
}
pub(crate) fn clear_material_2d_instances<M: Material2d>(
mut material_instances: ResMut<RenderMaterial2dInstances<M>>,
) {
material_instances.clear();
}
fn extract_mesh_materials_2d<M: Material2d>(
mut material_instances: ResMut<RenderMaterial2dInstances<M>>,
query: Extract<Query<(Entity, &ViewVisibility, &MeshMaterial2d<M>), With<Mesh2d>>>,
) {
material_instances.clear();
for (entity, view_visibility, material) in &query {
if view_visibility.get() {
material_instances.insert(entity.into(), material.id());
@ -344,20 +290,6 @@ fn extract_mesh_materials_2d<M: Material2d>(
}
}
/// Extracts default materials for 2D meshes with no [`MeshMaterial2d`].
pub(crate) fn extract_default_materials_2d(
mut material_instances: ResMut<RenderMaterial2dInstances<ColorMaterial>>,
query: Extract<Query<(Entity, &ViewVisibility), (With<Mesh2d>, Without<HasMaterial2d>)>>,
) {
let default_material: AssetId<ColorMaterial> = Handle::<ColorMaterial>::default().id();
for (entity, view_visibility) in &query {
if view_visibility.get() {
material_instances.insert(entity.into(), default_material);
}
}
}
/// Render pipeline data for a given [`Material2d`]
#[derive(Resource)]
pub struct Material2dPipeline<M: Material2d> {

View file

@ -30,8 +30,8 @@ use bevy::{
Extract, Render, RenderApp, RenderSet,
},
sprite::{
extract_mesh2d, DrawMesh2d, HasMaterial2d, Material2dBindGroupId, Mesh2dPipeline,
Mesh2dPipelineKey, Mesh2dTransforms, MeshFlags, RenderMesh2dInstance, SetMesh2dBindGroup,
extract_mesh2d, DrawMesh2d, Material2dBindGroupId, Mesh2dPipeline, Mesh2dPipelineKey,
Mesh2dTransforms, MeshFlags, RenderMesh2dInstance, SetMesh2dBindGroup,
SetMesh2dViewBindGroup,
},
};
@ -120,10 +120,8 @@ fn star(
commands.spawn(Camera2d);
}
// Require `HasMaterial2d` to indicate that no placeholder material should be rendeed.
/// A marker component for colored 2d meshes
#[derive(Component, Default)]
#[require(HasMaterial2d)]
pub struct ColoredMesh2d;
/// Custom pipeline for 2d meshes with vertex colors