From c6c8407f4406202f12aa57bdb6266d4c79dec99e Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sun, 15 Jan 2023 18:26:40 -0500 Subject: [PATCH 01/11] use `Material` for wireframes --- crates/bevy_pbr/src/render/wireframe.wgsl | 2 +- crates/bevy_pbr/src/wireframe.rs | 237 ++++++++-------------- 2 files changed, 81 insertions(+), 158 deletions(-) diff --git a/crates/bevy_pbr/src/render/wireframe.wgsl b/crates/bevy_pbr/src/render/wireframe.wgsl index 453ee5f8c1446..1ed85e95d0d17 100644 --- a/crates/bevy_pbr/src/render/wireframe.wgsl +++ b/crates/bevy_pbr/src/render/wireframe.wgsl @@ -61,4 +61,4 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput { @fragment fn fragment() -> @location(0) vec4 { return vec4(1.0, 1.0, 1.0, 1.0); -} +} \ No newline at end of file diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 9566afffb9242..060cee2adbd18 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -1,33 +1,20 @@ -use crate::MeshPipeline; -use crate::{ - DrawMesh, MeshPipelineKey, RenderMeshInstance, RenderMeshInstances, SetMeshBindGroup, - SetMeshViewBindGroup, -}; +use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin}; use bevy_app::Plugin; -use bevy_asset::{load_internal_asset, Handle}; -use bevy_core_pipeline::core_3d::Opaque3d; -use bevy_derive::{Deref, DerefMut}; -use bevy_ecs::{prelude::*, reflect::ReflectComponent}; -use bevy_reflect::std_traits::ReflectDefault; -use bevy_reflect::Reflect; +use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; +use bevy_ecs::prelude::*; +use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypeUuid}; use bevy_render::{ - extract_resource::{ExtractResource, ExtractResourcePlugin}, + extract_resource::ExtractResource, mesh::{Mesh, MeshVertexBufferLayout}, - render_asset::RenderAssets, - render_phase::{AddRenderCommand, DrawFunctions, RenderPhase, SetItemPipeline}, + prelude::Shader, render_resource::{ - PipelineCache, PolygonMode, RenderPipelineDescriptor, Shader, SpecializedMeshPipeline, - SpecializedMeshPipelineError, SpecializedMeshPipelines, + AsBindGroup, PolygonMode, RenderPipelineDescriptor, ShaderRef, SpecializedMeshPipelineError, }, - view::{ExtractedView, Msaa, VisibleEntities}, - RenderApp, RenderSet, }; -use bevy_render::{Extract, ExtractSchedule, Render}; -use bevy_utils::tracing::error; -use bevy_utils::EntityHashSet; pub const WIREFRAME_SHADER_HANDLE: Handle = Handle::weak_from_u128(192598014480025766); +/// A [`Plugin`] that draws wireframes. #[derive(Debug, Default)] pub struct WireframePlugin; @@ -43,164 +30,100 @@ impl Plugin for WireframePlugin { app.register_type::() .register_type::() .init_resource::() - .add_plugins((ExtractResourcePlugin::::default(),)); - - if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { - render_app - .add_render_command::() - .init_resource::>() - .init_resource::() - .add_systems(ExtractSchedule, extract_wireframes) - .add_systems(Render, queue_wireframes.in_set(RenderSet::QueueMeshes)); - } + .add_plugin(MaterialPlugin::::default()) + .add_system(apply_global) + .add_system(apply_material); } - fn finish(&self, app: &mut bevy_app::App) { - if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { - render_app.init_resource::(); - } - } -} - -/// Controls whether an entity should rendered in wireframe-mode if the [`WireframePlugin`] is enabled +/// Toggles wireframe rendering for any entity it is attached to. +/// +/// This requires the [`WireframePlugin`] to be enabled. #[derive(Component, Debug, Clone, Default, Reflect)] #[reflect(Component, Default)] pub struct Wireframe; +/// Configuration resource for [`WireframePlugin`]. #[derive(Resource, Debug, Clone, Default, ExtractResource, Reflect)] #[reflect(Resource)] pub struct WireframeConfig { - /// Whether to show wireframes for all meshes. If `false`, only meshes with a [`Wireframe`] component will be rendered. + /// Whether to show wireframes for all meshes. + /// If `false`, only meshes with a [`Wireframe`] component will be rendered. pub global: bool, } -#[derive(Resource, Default, Deref, DerefMut)] -pub struct Wireframes(EntityHashSet); - -fn extract_wireframes( - mut wireframes: ResMut, - query: Extract>>, +/// Applies the wireframe material to any mesh with a [`Wireframe`] component. +fn apply_material( + mut commands: Commands, + mut materials: ResMut>, + wireframes: Query, Without>)>, ) { - wireframes.clear(); - wireframes.extend(&query); -} - -#[derive(Resource, Clone)] -pub struct WireframePipeline { - mesh_pipeline: MeshPipeline, - shader: Handle, -} -impl FromWorld for WireframePipeline { - fn from_world(render_world: &mut World) -> Self { - WireframePipeline { - mesh_pipeline: render_world.resource::().clone(), - shader: WIREFRAME_SHADER_HANDLE, - } + for e in &wireframes { + commands + .entity(e) + .insert(materials.add(WireframeMaterial {})); } } -impl SpecializedMeshPipeline for WireframePipeline { - type Key = MeshPipelineKey; +/// Applies or removes a wireframe material on any mesh without a [`Wireframe`] component. +#[allow(clippy::type_complexity)] +fn apply_global( + mut commands: Commands, + config: Res, + mut materials: ResMut>, + meshes_without_material: Query< + Entity, + ( + With>, + Without, + Without>, + ), + >, + meshes_with_material: Query< + Entity, + ( + With>, + Without, + With>, + ), + >, +) { + if !config.is_changed() { + return; + } - fn specialize( - &self, - key: Self::Key, - layout: &MeshVertexBufferLayout, - ) -> Result { - let mut descriptor = self.mesh_pipeline.specialize(key, layout)?; - descriptor.vertex.shader = self.shader.clone_weak(); - descriptor - .vertex - .shader_defs - .push("MESH_BINDGROUP_1".into()); - descriptor.fragment.as_mut().unwrap().shader = self.shader.clone_weak(); - descriptor.primitive.polygon_mode = PolygonMode::Line; - descriptor.depth_stencil.as_mut().unwrap().bias.slope_scale = 1.0; - Ok(descriptor) + if config.global { + let global_material = materials.add(WireframeMaterial {}); + for e in &meshes_without_material { + commands.entity(e).insert(global_material.clone()); + } + } else if !config.global { + for e in &meshes_with_material { + commands.entity(e).remove::>(); + } } } -#[allow(clippy::too_many_arguments)] -fn queue_wireframes( - opaque_3d_draw_functions: Res>, - render_meshes: Res>, - render_mesh_instances: Res, - wireframes: Res, - wireframe_config: Res, - wireframe_pipeline: Res, - mut pipelines: ResMut>, - pipeline_cache: Res, - msaa: Res, - mut views: Query<(&ExtractedView, &VisibleEntities, &mut RenderPhase)>, -) { - let draw_custom = opaque_3d_draw_functions.read().id::(); - let msaa_key = MeshPipelineKey::from_msaa_samples(msaa.samples()); - for (view, visible_entities, mut opaque_phase) in &mut views { - let rangefinder = view.rangefinder3d(); +#[derive(Default, AsBindGroup, TypeUuid, Debug, Clone)] +#[uuid = "9e694f70-9963-4418-8bc1-3474c66b13b8"] +struct WireframeMaterial {} - let view_key = msaa_key | MeshPipelineKey::from_hdr(view.hdr); - let add_render_phase = |phase_item: (Entity, &RenderMeshInstance)| { - let (entity, mesh_instance) = phase_item; +impl Material for WireframeMaterial { + fn vertex_shader() -> ShaderRef { + WIREFRAME_SHADER_HANDLE.typed().into() + } - let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id) else { - return; - }; - let mut key = - view_key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); - if mesh.morph_targets.is_some() { - key |= MeshPipelineKey::MORPH_TARGETS; - } - let pipeline_id = - pipelines.specialize(&pipeline_cache, &wireframe_pipeline, key, &mesh.layout); - let pipeline_id = match pipeline_id { - Ok(id) => id, - Err(err) => { - error!("{}", err); - return; - } - }; - opaque_phase.add(Opaque3d { - entity, - pipeline: pipeline_id, - draw_function: draw_custom, - distance: rangefinder - .distance_translation(&mesh_instance.transforms.transform.translation), - batch_range: 0..1, - dynamic_offset: None, - }); - }; + fn fragment_shader() -> ShaderRef { + WIREFRAME_SHADER_HANDLE.typed().into() + } - if wireframe_config.global { - visible_entities - .entities - .iter() - .filter_map(|visible_entity| { - render_mesh_instances - .get(visible_entity) - .map(|mesh_instance| (*visible_entity, mesh_instance)) - }) - .for_each(add_render_phase); - } else { - visible_entities - .entities - .iter() - .filter_map(|visible_entity| { - if wireframes.contains(visible_entity) { - render_mesh_instances - .get(visible_entity) - .map(|mesh_instance| (*visible_entity, mesh_instance)) - } else { - None - } - }) - .for_each(add_render_phase); - } + fn specialize( + _pipeline: &MaterialPipeline, + descriptor: &mut RenderPipelineDescriptor, + _layout: &MeshVertexBufferLayout, + _key: MaterialPipelineKey, + ) -> Result<(), SpecializedMeshPipelineError> { + descriptor.primitive.polygon_mode = PolygonMode::Line; + descriptor.depth_stencil.as_mut().unwrap().bias.slope_scale = 1.0; + Ok(()) } } - -type DrawWireframes = ( - SetItemPipeline, - SetMeshViewBindGroup<0>, - SetMeshBindGroup<1>, - DrawMesh, -); From 09b58eb11d3479dc73fbe45237d96c7607d4a876 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Mon, 14 Aug 2023 16:33:03 -0400 Subject: [PATCH 02/11] fix for 0.11 --- crates/bevy_pbr/src/wireframe.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 060cee2adbd18..836159c4417b5 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -1,8 +1,8 @@ use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin}; -use bevy_app::Plugin; +use bevy_app::{Plugin, Update}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; use bevy_ecs::prelude::*; -use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypeUuid}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath, TypeUuid}; use bevy_render::{ extract_resource::ExtractResource, mesh::{Mesh, MeshVertexBufferLayout}, @@ -30,10 +30,11 @@ impl Plugin for WireframePlugin { app.register_type::() .register_type::() .init_resource::() - .add_plugin(MaterialPlugin::::default()) - .add_system(apply_global) - .add_system(apply_material); + .add_plugins(MaterialPlugin::::default()) + .add_systems(Update, apply_global) + .add_systems(Update, apply_material); } +} /// Toggles wireframe rendering for any entity it is attached to. /// @@ -103,7 +104,7 @@ fn apply_global( } } -#[derive(Default, AsBindGroup, TypeUuid, Debug, Clone)] +#[derive(Default, AsBindGroup, TypeUuid, TypePath, Debug, Clone)] #[uuid = "9e694f70-9963-4418-8bc1-3474c66b13b8"] struct WireframeMaterial {} From 4b7f6780330ecf0f9cac8175e7fd139a26d53647 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sun, 1 Oct 2023 16:02:47 -0400 Subject: [PATCH 03/11] address some PR comments --- crates/bevy_pbr/src/wireframe.rs | 44 ++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 836159c4417b5..f3940697bc2c7 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -1,5 +1,5 @@ use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin}; -use bevy_app::{Plugin, Update}; +use bevy_app::{Plugin, Startup, Update}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; use bevy_ecs::prelude::*; use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath, TypeUuid}; @@ -31,8 +31,8 @@ impl Plugin for WireframePlugin { .register_type::() .init_resource::() .add_plugins(MaterialPlugin::::default()) - .add_systems(Update, apply_global) - .add_systems(Update, apply_material); + .add_systems(Startup, setup) + .add_systems(Update, (apply_global, apply_material)); } } @@ -52,17 +52,37 @@ pub struct WireframeConfig { pub global: bool, } +#[derive(Resource)] +struct GlobalWireframeMaterial { + // This handle will be reused when the global config is enabled + handle: Handle, +} + +fn setup(mut commands: Commands, mut materials: ResMut>) { + // Create the handle used for the global material + commands.insert_resource(GlobalWireframeMaterial { + handle: materials.add(WireframeMaterial {}), + }); +} + /// Applies the wireframe material to any mesh with a [`Wireframe`] component. fn apply_material( mut commands: Commands, mut materials: ResMut>, wireframes: Query, Without>)>, + mut removed_wireframes: RemovedComponents, ) { + for e in removed_wireframes.iter() { + if let Some(mut commands) = commands.get_entity(e) { + commands.remove::>(); + } + } + + let mut wireframes_to_spawn = vec![]; for e in &wireframes { - commands - .entity(e) - .insert(materials.add(WireframeMaterial {})); + wireframes_to_spawn.push((e, materials.add(WireframeMaterial {}))); } + commands.insert_or_spawn_batch(wireframes_to_spawn); } /// Applies or removes a wireframe material on any mesh without a [`Wireframe`] component. @@ -79,7 +99,7 @@ fn apply_global( Without>, ), >, - meshes_with_material: Query< + meshes_with_global_material: Query< Entity, ( With>, @@ -87,18 +107,22 @@ fn apply_global( With>, ), >, + global_material: Res, ) { if !config.is_changed() { return; } if config.global { - let global_material = materials.add(WireframeMaterial {}); + let mut material_to_spawn = vec![]; for e in &meshes_without_material { - commands.entity(e).insert(global_material.clone()); + // We only add the material handle but not the Wireframe component + // This makes it easy to detect which mesh is using the global material and which ones are user specified + material_to_spawn.push((e, global_material.handle.clone())); } + commands.insert_or_spawn_batch(material_to_spawn); } else if !config.global { - for e in &meshes_with_material { + for e in &meshes_with_global_material { commands.entity(e).remove::>(); } } From f7f5f8809ef3b01881d471f77dcc03ce8e7408db Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sun, 1 Oct 2023 16:13:40 -0400 Subject: [PATCH 04/11] fix --- crates/bevy_pbr/src/wireframe.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index f3940697bc2c7..ed6941e756f46 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -1,6 +1,6 @@ use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin}; use bevy_app::{Plugin, Startup, Update}; -use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; +use bevy_asset::{load_internal_asset, Asset, Assets, Handle}; use bevy_ecs::prelude::*; use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath, TypeUuid}; use bevy_render::{ @@ -72,7 +72,7 @@ fn apply_material( wireframes: Query, Without>)>, mut removed_wireframes: RemovedComponents, ) { - for e in removed_wireframes.iter() { + for e in removed_wireframes.read() { if let Some(mut commands) = commands.get_entity(e) { commands.remove::>(); } @@ -90,7 +90,6 @@ fn apply_material( fn apply_global( mut commands: Commands, config: Res, - mut materials: ResMut>, meshes_without_material: Query< Entity, ( @@ -128,17 +127,17 @@ fn apply_global( } } -#[derive(Default, AsBindGroup, TypeUuid, TypePath, Debug, Clone)] +#[derive(Default, AsBindGroup, TypeUuid, TypePath, Debug, Clone, Asset)] #[uuid = "9e694f70-9963-4418-8bc1-3474c66b13b8"] struct WireframeMaterial {} impl Material for WireframeMaterial { fn vertex_shader() -> ShaderRef { - WIREFRAME_SHADER_HANDLE.typed().into() + WIREFRAME_SHADER_HANDLE.into() } fn fragment_shader() -> ShaderRef { - WIREFRAME_SHADER_HANDLE.typed().into() + WIREFRAME_SHADER_HANDLE.into() } fn specialize( From c9a012f4c16f9147de8cad8802c3459fd35aff57 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sun, 1 Oct 2023 16:35:44 -0400 Subject: [PATCH 05/11] improve example --- examples/3d/wireframe.rs | 42 +++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/examples/3d/wireframe.rs b/examples/3d/wireframe.rs index 0192b6ee43709..1413cf7eec183 100644 --- a/examples/3d/wireframe.rs +++ b/examples/3d/wireframe.rs @@ -3,40 +3,38 @@ use bevy::{ pbr::wireframe::{Wireframe, WireframeConfig, WireframePlugin}, prelude::*, - render::{render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin}, + render::{ + render_resource::WgpuFeatures, + settings::{RenderCreation, WgpuSettings}, + RenderPlugin, + }, }; fn main() { App::new() .add_plugins(( DefaultPlugins.set(RenderPlugin { - render_creation: WgpuSettings { + render_creation: RenderCreation::Automatic(WgpuSettings { + // WARN this is a native only feature. It will not work with webgl or webgpu features: WgpuFeatures::POLYGON_MODE_LINE, ..default() - } - .into(), + }), + ..default() }), + // You need to add this plugin to enable wireframe rendering WireframePlugin, )) .add_systems(Startup, setup) + .add_systems(Update, toggle_global_wireframe) .run(); } /// set up a simple 3D scene fn setup( mut commands: Commands, - mut wireframe_config: ResMut, mut meshes: ResMut>, mut materials: ResMut>, ) { - // To draw the wireframe on all entities, set this to 'true' - wireframe_config.global = false; - // plane - commands.spawn(PbrBundle { - mesh: meshes.add(shape::Plane::from_size(5.0).into()), - material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), - ..default() - }); // cube commands.spawn(( PbrBundle { @@ -48,6 +46,14 @@ fn setup( // This enables wireframe drawing on this entity Wireframe, )); + + // plane + commands.spawn(PbrBundle { + mesh: meshes.add(shape::Plane::from_size(5.0).into()), + material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), + ..default() + }); + // light commands.spawn(PointLightBundle { transform: Transform::from_xyz(4.0, 8.0, 4.0), @@ -59,3 +65,13 @@ fn setup( ..default() }); } + +fn toggle_global_wireframe( + mut wireframe_config: ResMut, + keyboard_input: Res>, +) { + if keyboard_input.just_pressed(KeyCode::T) { + // To draw the wireframe on all entities, set this to 'true' + wireframe_config.global = !wireframe_config.global; + } +} From 6f35da3bb9b110652f1bed933a412cff28ac4173 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sun, 1 Oct 2023 16:39:43 -0400 Subject: [PATCH 06/11] remove unnecessary default --- examples/3d/wireframe.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/3d/wireframe.rs b/examples/3d/wireframe.rs index 1413cf7eec183..ee73a0b2f3218 100644 --- a/examples/3d/wireframe.rs +++ b/examples/3d/wireframe.rs @@ -19,7 +19,6 @@ fn main() { features: WgpuFeatures::POLYGON_MODE_LINE, ..default() }), - ..default() }), // You need to add this plugin to enable wireframe rendering WireframePlugin, From de097f447221b18363bfd777c59b2e89dda93f17 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sun, 1 Oct 2023 19:32:01 -0400 Subject: [PATCH 07/11] docs and PR fixes --- crates/bevy_pbr/src/wireframe.rs | 26 ++++++++++++++++++++------ examples/3d/wireframe.rs | 8 ++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index ed6941e756f46..6392b4d03da11 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -15,6 +15,14 @@ use bevy_render::{ pub const WIREFRAME_SHADER_HANDLE: Handle = Handle::weak_from_u128(192598014480025766); /// A [`Plugin`] that draws wireframes. +/// +/// Wireframes currently do not work when using webgl or webgpu. +/// Supported platforms: +/// - DX12 +/// - Vulkan +/// - Metal +/// +/// This is a native only feature. #[derive(Debug, Default)] pub struct WireframePlugin; @@ -31,8 +39,11 @@ impl Plugin for WireframePlugin { .register_type::() .init_resource::() .add_plugins(MaterialPlugin::::default()) - .add_systems(Startup, setup) - .add_systems(Update, (apply_global, apply_material)); + .add_systems(Startup, setup_global_wireframe_material) + .add_systems( + Update, + (apply_global_wireframe_material, apply_wireframe_material), + ); } } @@ -58,15 +69,18 @@ struct GlobalWireframeMaterial { handle: Handle, } -fn setup(mut commands: Commands, mut materials: ResMut>) { +fn setup_global_wireframe_material( + mut commands: Commands, + mut materials: ResMut>, +) { // Create the handle used for the global material commands.insert_resource(GlobalWireframeMaterial { handle: materials.add(WireframeMaterial {}), }); } -/// Applies the wireframe material to any mesh with a [`Wireframe`] component. -fn apply_material( +/// Applies or remove the wireframe material to any mesh with a [`Wireframe`] component. +fn apply_wireframe_material( mut commands: Commands, mut materials: ResMut>, wireframes: Query, Without>)>, @@ -87,7 +101,7 @@ fn apply_material( /// Applies or removes a wireframe material on any mesh without a [`Wireframe`] component. #[allow(clippy::type_complexity)] -fn apply_global( +fn apply_global_wireframe_material( mut commands: Commands, config: Res, meshes_without_material: Query< diff --git a/examples/3d/wireframe.rs b/examples/3d/wireframe.rs index ee73a0b2f3218..bd98a31290fbb 100644 --- a/examples/3d/wireframe.rs +++ b/examples/3d/wireframe.rs @@ -1,4 +1,12 @@ //! Showcases wireframe rendering. +//! +//! Wireframes currently do not work when using webgl or webgpu. +//! Supported platforms: +//! - DX12 +//! - Vulkan +//! - Metal +//! +//! This is a native only feature. use bevy::{ pbr::wireframe::{Wireframe, WireframeConfig, WireframePlugin}, From 4983a417a36b8bcb6373e200834f441ddd3ba28a Mon Sep 17 00:00:00 2001 From: IceSentry Date: Wed, 4 Oct 2023 13:30:23 -0400 Subject: [PATCH 08/11] yeet vertex shader --- crates/bevy_pbr/src/render/wireframe.wgsl | 62 +---------------------- crates/bevy_pbr/src/wireframe.rs | 4 -- 2 files changed, 2 insertions(+), 64 deletions(-) diff --git a/crates/bevy_pbr/src/render/wireframe.wgsl b/crates/bevy_pbr/src/render/wireframe.wgsl index 1ed85e95d0d17..c170273d08d3f 100644 --- a/crates/bevy_pbr/src/render/wireframe.wgsl +++ b/crates/bevy_pbr/src/render/wireframe.wgsl @@ -1,64 +1,6 @@ -#import bevy_pbr::mesh_bindings mesh -#import bevy_pbr::mesh_functions get_model_matrix, mesh_position_local_to_clip -#import bevy_pbr::morph - -#ifdef SKINNED - #import bevy_pbr::skinning -#endif - -struct Vertex { - @builtin(instance_index) instance_index: u32, - @location(0) position: vec3, -#ifdef SKINNED - @location(5) joint_indexes: vec4, - @location(6) joint_weights: vec4, -#endif -#ifdef MORPH_TARGETS - @builtin(vertex_index) index: u32, -#endif -}; - -struct VertexOutput { - @builtin(position) clip_position: vec4, -}; - - -#ifdef MORPH_TARGETS -fn morph_vertex(vertex_in: Vertex) -> Vertex { - var vertex = vertex_in; - let weight_count = bevy_pbr::morph::layer_count(); - for (var i: u32 = 0u; i < weight_count; i ++) { - let weight = bevy_pbr::morph::weight_at(i); - if weight == 0.0 { - continue; - } - vertex.position += weight * bevy_pbr::morph::morph(vertex.index, bevy_pbr::morph::position_offset, i); - } - return vertex; -} -#endif - -@vertex -fn vertex(vertex_no_morph: Vertex) -> VertexOutput { - -#ifdef MORPH_TARGETS - var vertex = morph_vertex(vertex_no_morph); -#else - var vertex = vertex_no_morph; -#endif - -#ifdef SKINNED - let model = bevy_pbr::skinning::skin_model(vertex.joint_indexes, vertex.joint_weights); -#else - let model = get_model_matrix(vertex.instance_index); -#endif - - var out: VertexOutput; - out.clip_position = mesh_position_local_to_clip(model, vec4(vertex.position, 1.0)); - return out; -} +#import bevy_pbr::mesh_vertex_output MeshVertexOutput @fragment -fn fragment() -> @location(0) vec4 { +fn fragment(in: MeshVertexOutput) -> @location(0) vec4 { return vec4(1.0, 1.0, 1.0, 1.0); } \ No newline at end of file diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 6392b4d03da11..92f8274e4a78c 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -146,10 +146,6 @@ fn apply_global_wireframe_material( struct WireframeMaterial {} impl Material for WireframeMaterial { - fn vertex_shader() -> ShaderRef { - WIREFRAME_SHADER_HANDLE.into() - } - fn fragment_shader() -> ShaderRef { WIREFRAME_SHADER_HANDLE.into() } From ceb163d8e0626070cc78fbc29ea944fcef6d6f94 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Thu, 5 Oct 2023 15:00:08 -0400 Subject: [PATCH 09/11] support NoWireframe --- crates/bevy_pbr/src/wireframe.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index d7b50139bd0c7..f121c51194760 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -118,6 +118,7 @@ fn apply_global_wireframe_material( ( With>, Without, + Without, Without>, ), >, @@ -126,6 +127,7 @@ fn apply_global_wireframe_material( ( With>, Without, + Without, With>, ), >, From bd19b545afaa96f3ea93868361fc6b1d86a5af71 Mon Sep 17 00:00:00 2001 From: IceSentry Date: Thu, 5 Oct 2023 15:57:49 -0400 Subject: [PATCH 10/11] use color constants where possible --- examples/3d/wireframe.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/3d/wireframe.rs b/examples/3d/wireframe.rs index 180017e80beff..b96492bb88ede 100644 --- a/examples/3d/wireframe.rs +++ b/examples/3d/wireframe.rs @@ -49,7 +49,7 @@ fn setup( // plane commands.spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Plane::from_size(5.0))), - material: materials.add(Color::rgb(0.3, 0.3, 0.5).into()), + material: materials.add(Color::BLUE.into()), ..default() }); @@ -57,7 +57,7 @@ fn setup( commands .spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), - material: materials.add(Color::rgb(0.8, 0.1, 0.1).into()), + material: materials.add(Color::RED.into()), transform: Transform::from_xyz(-1.0, 0.5, -1.0), ..default() }) @@ -65,7 +65,7 @@ fn setup( // Orange cube: Follows global wireframe setting commands.spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), - material: materials.add(Color::rgb(0.8, 0.8, 0.1).into()), + material: materials.add(Color::ORANGE.into()), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..default() }); @@ -73,7 +73,7 @@ fn setup( commands .spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), - material: materials.add(Color::rgb(0.1, 0.8, 0.1).into()), + material: materials.add(Color::GREEN.into()), transform: Transform::from_xyz(1.0, 0.5, 1.0), ..default() }) From 4bfd58d35ab42734c3440c2811a3424f6f4514bc Mon Sep 17 00:00:00 2001 From: IceSentry Date: Sun, 8 Oct 2023 19:30:44 -0400 Subject: [PATCH 11/11] Update crates/bevy_pbr/src/wireframe.rs Co-authored-by: Alice Cecile --- crates/bevy_pbr/src/wireframe.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index f121c51194760..5aff6e4df97b3 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -17,7 +17,7 @@ pub const WIREFRAME_SHADER_HANDLE: Handle = Handle::weak_from_u128(19259 /// A [`Plugin`] that draws wireframes. /// /// Wireframes currently do not work when using webgl or webgpu. -/// Supported platforms: +/// Supported rendering backends: /// - DX12 /// - Vulkan /// - Metal