wireframe/
wireframe.rs

1//! Showcases wireframe rendering.
2//!
3//! Wireframes currently do not work when using webgl or webgpu.
4//! Supported platforms:
5//! - DX12
6//! - Vulkan
7//! - Metal
8//!
9//! This is a native only feature.
10
11use bevy::{
12    color::palettes::css::*,
13    pbr::wireframe::{NoWireframe, Wireframe, WireframeColor, WireframeConfig, WireframePlugin},
14    prelude::*,
15    render::{
16        render_resource::WgpuFeatures,
17        settings::{RenderCreation, WgpuSettings},
18        RenderPlugin,
19    },
20};
21
22fn main() {
23    App::new()
24        .add_plugins((
25            DefaultPlugins.set(RenderPlugin {
26                render_creation: RenderCreation::Automatic(WgpuSettings {
27                    // WARN this is a native only feature. It will not work with webgl or webgpu
28                    features: WgpuFeatures::POLYGON_MODE_LINE,
29                    ..default()
30                }),
31                ..default()
32            }),
33            // You need to add this plugin to enable wireframe rendering
34            WireframePlugin::default(),
35        ))
36        // Wireframes can be configured with this resource. This can be changed at runtime.
37        .insert_resource(WireframeConfig {
38            // The global wireframe config enables drawing of wireframes on every mesh,
39            // except those with `NoWireframe`. Meshes with `Wireframe` will always have a wireframe,
40            // regardless of the global configuration.
41            global: true,
42            // Controls the default color of all wireframes. Used as the default color for global wireframes.
43            // Can be changed per mesh using the `WireframeColor` component.
44            default_color: WHITE.into(),
45        })
46        .add_systems(Startup, setup)
47        .add_systems(Update, update_colors)
48        .run();
49}
50
51/// set up a simple 3D scene
52fn setup(
53    mut commands: Commands,
54    mut meshes: ResMut<Assets<Mesh>>,
55    mut materials: ResMut<Assets<StandardMaterial>>,
56) {
57    // Red cube: Never renders a wireframe
58    commands.spawn((
59        Mesh3d(meshes.add(Cuboid::default())),
60        MeshMaterial3d(materials.add(Color::from(RED))),
61        Transform::from_xyz(-1.0, 0.5, -1.0),
62        NoWireframe,
63    ));
64    // Orange cube: Follows global wireframe setting
65    commands.spawn((
66        Mesh3d(meshes.add(Cuboid::default())),
67        MeshMaterial3d(materials.add(Color::from(ORANGE))),
68        Transform::from_xyz(0.0, 0.5, 0.0),
69    ));
70    // Green cube: Always renders a wireframe
71    commands.spawn((
72        Mesh3d(meshes.add(Cuboid::default())),
73        MeshMaterial3d(materials.add(Color::from(LIME))),
74        Transform::from_xyz(1.0, 0.5, 1.0),
75        Wireframe,
76        // This lets you configure the wireframe color of this entity.
77        // If not set, this will use the color in `WireframeConfig`
78        WireframeColor { color: LIME.into() },
79    ));
80
81    // plane
82    commands.spawn((
83        Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
84        MeshMaterial3d(materials.add(Color::from(BLUE))),
85        // You can insert this component without the `Wireframe` component
86        // to override the color of the global wireframe for this mesh
87        WireframeColor {
88            color: BLACK.into(),
89        },
90    ));
91
92    // light
93    commands.spawn((PointLight::default(), Transform::from_xyz(2.0, 4.0, 2.0)));
94
95    // camera
96    commands.spawn((
97        Camera3d::default(),
98        Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
99    ));
100
101    // Text used to show controls
102    commands.spawn((
103        Text::default(),
104        Node {
105            position_type: PositionType::Absolute,
106            top: px(12),
107            left: px(12),
108            ..default()
109        },
110    ));
111}
112
113/// This system let's you toggle various wireframe settings
114fn update_colors(
115    keyboard_input: Res<ButtonInput<KeyCode>>,
116    mut config: ResMut<WireframeConfig>,
117    mut wireframe_colors: Query<&mut WireframeColor, With<Wireframe>>,
118    mut text: Single<&mut Text>,
119) {
120    text.0 = format!(
121        "Controls
122---------------
123Z - Toggle global
124X - Change global color
125C - Change color of the green cube wireframe
126
127WireframeConfig
128-------------
129Global: {}
130Color: {:?}",
131        config.global, config.default_color,
132    );
133
134    // Toggle showing a wireframe on all meshes
135    if keyboard_input.just_pressed(KeyCode::KeyZ) {
136        config.global = !config.global;
137    }
138
139    // Toggle the global wireframe color
140    if keyboard_input.just_pressed(KeyCode::KeyX) {
141        config.default_color = if config.default_color == WHITE.into() {
142            DEEP_PINK.into()
143        } else {
144            WHITE.into()
145        };
146    }
147
148    // Toggle the color of a wireframe using WireframeColor and not the global color
149    if keyboard_input.just_pressed(KeyCode::KeyC) {
150        for mut color in &mut wireframe_colors {
151            color.color = if color.color == LIME.into() {
152                RED.into()
153            } else {
154                LIME.into()
155            };
156        }
157    }
158}