Skip to content

Commit 8403c41

Browse files
authored
Use WireframeColor to override global color (#13034)
# Objective - The docs says the WireframeColor is supposed to override the default global color but it doesn't. ## Solution - Use WireframeColor to override global color like docs said it was supposed to do. - Updated the example to document this feature - I also took the opportunity to clean up the code a bit Fixes #13032
1 parent b3d3daa commit 8403c41

File tree

2 files changed

+51
-24
lines changed

2 files changed

+51
-24
lines changed

crates/bevy_pbr/src/wireframe.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ pub struct Wireframe;
6464
/// it will still affect the color of the wireframe when [`WireframeConfig::global`] is set to true.
6565
///
6666
/// This overrides the [`WireframeConfig::default_color`].
67+
//
68+
// TODO: consider caching materials based on this color.
69+
// This could blow up in size if people use random colored wireframes for each mesh.
70+
// It will also be important to remove unused materials from the cache.
6771
#[derive(Component, Debug, Clone, Default, Reflect)]
6872
#[reflect(Component, Default)]
6973
pub struct WireframeColor {
@@ -155,19 +159,12 @@ fn apply_wireframe_material(
155159
}
156160
}
157161

158-
let mut wireframes_to_spawn = vec![];
159-
for (e, wireframe_color) in &wireframes {
160-
let material = if let Some(wireframe_color) = wireframe_color {
161-
materials.add(WireframeMaterial {
162-
color: wireframe_color.color.into(),
163-
})
164-
} else {
165-
// If there's no color specified we can use the global material since it's already set to use the default_color
166-
global_material.handle.clone()
167-
};
168-
wireframes_to_spawn.push((e, material));
162+
let mut material_to_spawn = vec![];
163+
for (e, maybe_color) in &wireframes {
164+
let material = get_wireframe_material(maybe_color, &mut materials, &global_material);
165+
material_to_spawn.push((e, material));
169166
}
170-
commands.insert_or_spawn_batch(wireframes_to_spawn);
167+
commands.insert_or_spawn_batch(material_to_spawn);
171168
}
172169

173170
type WireframeFilter = (With<Handle<Mesh>>, Without<Wireframe>, Without<NoWireframe>);
@@ -176,16 +173,21 @@ type WireframeFilter = (With<Handle<Mesh>>, Without<Wireframe>, Without<NoWirefr
176173
fn apply_global_wireframe_material(
177174
mut commands: Commands,
178175
config: Res<WireframeConfig>,
179-
meshes_without_material: Query<Entity, (WireframeFilter, Without<Handle<WireframeMaterial>>)>,
176+
meshes_without_material: Query<
177+
(Entity, Option<&WireframeColor>),
178+
(WireframeFilter, Without<Handle<WireframeMaterial>>),
179+
>,
180180
meshes_with_global_material: Query<Entity, (WireframeFilter, With<Handle<WireframeMaterial>>)>,
181181
global_material: Res<GlobalWireframeMaterial>,
182+
mut materials: ResMut<Assets<WireframeMaterial>>,
182183
) {
183184
if config.global {
184185
let mut material_to_spawn = vec![];
185-
for e in &meshes_without_material {
186+
for (e, maybe_color) in &meshes_without_material {
187+
let material = get_wireframe_material(maybe_color, &mut materials, &global_material);
186188
// We only add the material handle but not the Wireframe component
187189
// This makes it easy to detect which mesh is using the global material and which ones are user specified
188-
material_to_spawn.push((e, global_material.handle.clone()));
190+
material_to_spawn.push((e, material));
189191
}
190192
commands.insert_or_spawn_batch(material_to_spawn);
191193
} else {
@@ -195,6 +197,22 @@ fn apply_global_wireframe_material(
195197
}
196198
}
197199

200+
/// Gets an handle to a wireframe material with a fallback on the default material
201+
fn get_wireframe_material(
202+
maybe_color: Option<&WireframeColor>,
203+
wireframe_materials: &mut Assets<WireframeMaterial>,
204+
global_material: &GlobalWireframeMaterial,
205+
) -> Handle<WireframeMaterial> {
206+
if let Some(wireframe_color) = maybe_color {
207+
wireframe_materials.add(WireframeMaterial {
208+
color: wireframe_color.color.into(),
209+
})
210+
} else {
211+
// If there's no color specified we can use the global material since it's already set to use the default_color
212+
global_material.handle.clone()
213+
}
214+
}
215+
198216
#[derive(Default, AsBindGroup, TypePath, Debug, Clone, Asset)]
199217
pub struct WireframeMaterial {
200218
#[uniform(0)]
@@ -213,7 +231,9 @@ impl Material for WireframeMaterial {
213231
_key: MaterialPipelineKey<Self>,
214232
) -> Result<(), SpecializedMeshPipelineError> {
215233
descriptor.primitive.polygon_mode = PolygonMode::Line;
216-
descriptor.depth_stencil.as_mut().unwrap().bias.slope_scale = 1.0;
234+
if let Some(depth_stencil) = descriptor.depth_stencil.as_mut() {
235+
depth_stencil.bias.slope_scale = 1.0;
236+
}
217237
Ok(())
218238
}
219239
}

examples/3d/wireframe.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,6 @@ fn setup(
5454
mut meshes: ResMut<Assets<Mesh>>,
5555
mut materials: ResMut<Assets<StandardMaterial>>,
5656
) {
57-
// plane
58-
commands.spawn(PbrBundle {
59-
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
60-
material: materials.add(Color::from(BLUE)),
61-
..default()
62-
});
63-
6457
// Red cube: Never renders a wireframe
6558
commands.spawn((
6659
PbrBundle {
@@ -92,6 +85,20 @@ fn setup(
9285
WireframeColor { color: LIME.into() },
9386
));
9487

88+
// plane
89+
commands.spawn((
90+
PbrBundle {
91+
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
92+
material: materials.add(Color::from(BLUE)),
93+
..default()
94+
},
95+
// You can insert this component without the `Wireframe` component
96+
// to override the color of the global wireframe for this mesh
97+
WireframeColor {
98+
color: BLACK.into(),
99+
},
100+
));
101+
95102
// light
96103
commands.spawn(PointLightBundle {
97104
transform: Transform::from_xyz(2.0, 4.0, 2.0),
@@ -119,7 +126,7 @@ fn setup(
119126
fn update_colors(
120127
keyboard_input: Res<ButtonInput<KeyCode>>,
121128
mut config: ResMut<WireframeConfig>,
122-
mut wireframe_colors: Query<&mut WireframeColor>,
129+
mut wireframe_colors: Query<&mut WireframeColor, With<Wireframe>>,
123130
mut text: Query<&mut Text>,
124131
) {
125132
text.single_mut().sections[0].value = format!(

0 commit comments

Comments
 (0)