diff --git a/crates/bevy_gizmos/Cargo.toml b/crates/bevy_gizmos/Cargo.toml index 3a264c6244..a7f9f4b778 100644 --- a/crates/bevy_gizmos/Cargo.toml +++ b/crates/bevy_gizmos/Cargo.toml @@ -16,7 +16,6 @@ bevy_render = ["dep:bevy_render", "bevy_core_pipeline"] [dependencies] # Bevy bevy_pbr = { path = "../bevy_pbr", version = "0.16.0-dev", optional = true } -bevy_sprite = { path = "../bevy_sprite", version = "0.16.0-dev", optional = true } bevy_app = { path = "../bevy_app", version = "0.16.0-dev" } bevy_color = { path = "../bevy_color", version = "0.16.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.16.0-dev" } diff --git a/crates/bevy_gizmos/src/config.rs b/crates/bevy_gizmos/src/config.rs index bba3ff284c..da8916077c 100644 --- a/crates/bevy_gizmos/src/config.rs +++ b/crates/bevy_gizmos/src/config.rs @@ -2,10 +2,7 @@ pub use bevy_gizmos_macros::GizmoConfigGroup; -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite") -))] +#[cfg(feature = "bevy_render")] use {crate::GizmoAsset, bevy_asset::Handle, bevy_ecs::component::Component}; use bevy_ecs::{reflect::ReflectResource, resource::Resource}; @@ -238,10 +235,7 @@ impl Default for GizmoLineConfig { } } -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite") -))] +#[cfg(feature = "bevy_render")] #[derive(Component)] pub(crate) struct GizmoMeshConfig { pub line_perspective: bool, diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index fdc2243233..5790d33988 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -26,10 +26,8 @@ extern crate self as bevy_gizmos; #[derive(SystemSet, Clone, Debug, Hash, PartialEq, Eq)] pub enum GizmoRenderSystem { /// Adds gizmos to the [`Transparent2d`](bevy_core_pipeline::core_2d::Transparent2d) render phase - #[cfg(feature = "bevy_sprite")] QueueLineGizmos2d, /// Adds gizmos to the [`Transparent3d`](bevy_core_pipeline::core_3d::Transparent3d) render phase - #[cfg(feature = "bevy_pbr")] QueueLineGizmos3d, } @@ -46,13 +44,16 @@ pub mod grid; pub mod primitives; pub mod retained; pub mod rounded_box; +#[cfg(feature = "bevy_render")] +mod view; #[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))] pub mod light; -#[cfg(all(feature = "bevy_sprite", feature = "bevy_render"))] +#[cfg(feature = "bevy_render")] mod pipeline_2d; -#[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))] + +#[cfg(feature = "bevy_render")] mod pipeline_3d; /// The gizmos prelude. @@ -85,13 +86,12 @@ use bevy_ecs::{ schedule::{IntoSystemConfigs, SystemSet}, system::{Res, ResMut}, }; -use bevy_math::{Vec3, Vec4}; +use bevy_math::Vec4; use bevy_reflect::TypePath; +#[cfg(feature = "bevy_render")] +use view::OnlyViewLayout; -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite") -))] +#[cfg(feature = "bevy_render")] use crate::config::GizmoMeshConfig; use crate::{config::ErasedGizmoConfigGroup, gizmos::GizmoBuffer}; @@ -125,10 +125,7 @@ use { bytemuck::cast_slice, }; -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite"), -))] +#[cfg(feature = "bevy_render")] use bevy_render::render_resource::{VertexAttribute, VertexBufferLayout, VertexStepMode}; use bevy_time::Fixed; use bevy_utils::TypeIdMap; @@ -146,9 +143,10 @@ const LINE_SHADER_HANDLE: Handle = weak_handle!("15dc5869-ad30-4664-b35a const LINE_JOINT_SHADER_HANDLE: Handle = weak_handle!("7b5bdda5-df81-4711-a6cf-e587700de6f2"); -/// A [`Plugin`] that provides an immediate mode drawing api for visual debugging. +/// A [`Plugin`] for the [`RenderApp`] that provides an immediate mode drawing api for visual debugging. /// -/// Requires to be loaded after [`PbrPlugin`](bevy_pbr::PbrPlugin) or [`SpritePlugin`](bevy_sprite::SpritePlugin). +/// Additionally, it can support debugging light when the `bevy_pbr` feature is enabled, +/// see [`LightGizmoPlugin`] #[derive(Default)] pub struct GizmoPlugin; @@ -189,19 +187,8 @@ impl Plugin for GizmoPlugin { ); render_app.add_systems(ExtractSchedule, (extract_gizmo_data, extract_linegizmos)); - - #[cfg(feature = "bevy_sprite")] - if app.is_plugin_added::() { - app.add_plugins(pipeline_2d::LineGizmo2dPlugin); - } else { - tracing::warn!("bevy_sprite feature is enabled but bevy_sprite::SpritePlugin was not detected. Are you sure you loaded GizmoPlugin after SpritePlugin?"); - } - #[cfg(feature = "bevy_pbr")] - if app.is_plugin_added::() { - app.add_plugins(pipeline_3d::LineGizmo3dPlugin); - } else { - tracing::warn!("bevy_pbr feature is enabled but bevy_pbr::PbrPlugin was not detected. Are you sure you loaded GizmoPlugin after PbrPlugin?"); - } + app.add_plugins(pipeline_3d::LineGizmo3dPlugin) + .add_plugins(pipeline_2d::LineGizmo2dPlugin); } else { tracing::warn!("bevy_render feature is enabled but RenderApp was not detected. Are you sure you loaded GizmoPlugin after RenderPlugin?"); } @@ -222,9 +209,11 @@ impl Plugin for GizmoPlugin { ), ); - render_app.insert_resource(LineGizmoUniformBindgroupLayout { - layout: line_layout, - }); + render_app + .init_resource::() + .insert_resource(LineGizmoUniformBindgroupLayout { + layout: line_layout, + }); } } @@ -474,7 +463,6 @@ fn extract_gizmo_data( #[cfg(feature = "webgl")] _padding: Default::default(), }, - #[cfg(any(feature = "bevy_pbr", feature = "bevy_sprite"))] GizmoMeshConfig { line_perspective: config.line.perspective, line_style: config.line.style, @@ -503,7 +491,7 @@ struct LineGizmoUniform { line_scale: f32, /// WebGL2 structs must be 16 byte aligned. #[cfg(feature = "webgl")] - _padding: Vec3, + _padding: bevy_math::Vec3, } /// A collection of gizmos. @@ -634,7 +622,7 @@ impl RenderCommand

for SetLineGizmoBindGroup #[inline] fn render<'w>( _item: &P, - _view: ROQueryItem<'w, Self::ViewQuery>, + _views: ROQueryItem<'w, Self::ViewQuery>, uniform_index: Option>, bind_group: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, @@ -653,10 +641,7 @@ impl RenderCommand

for SetLineGizmoBindGroup #[cfg(feature = "bevy_render")] struct DrawLineGizmo; -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite") -))] +#[cfg(feature = "bevy_render")] impl RenderCommand

for DrawLineGizmo { type Param = SRes>; type ViewQuery = (); @@ -716,10 +701,7 @@ impl RenderCommand

for DrawLineGizmo #[cfg(feature = "bevy_render")] struct DrawLineJointGizmo; -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite") -))] +#[cfg(feature = "bevy_render")] impl RenderCommand

for DrawLineJointGizmo { type Param = SRes>; type ViewQuery = (); @@ -789,10 +771,7 @@ impl RenderCommand

for DrawLineJointGizmo { } } -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite") -))] +#[cfg(feature = "bevy_render")] fn line_gizmo_vertex_buffer_layouts(strip: bool) -> Vec { use VertexFormat::*; let mut position_layout = VertexBufferLayout { @@ -847,10 +826,7 @@ fn line_gizmo_vertex_buffer_layouts(strip: bool) -> Vec { } } -#[cfg(all( - feature = "bevy_render", - any(feature = "bevy_pbr", feature = "bevy_sprite") -))] +#[cfg(feature = "bevy_render")] fn line_joint_gizmo_vertex_buffer_layouts() -> Vec { use VertexFormat::*; let mut position_layout = VertexBufferLayout { diff --git a/crates/bevy_gizmos/src/pipeline_2d.rs b/crates/bevy_gizmos/src/pipeline_2d.rs index 72a2428ff0..8bbb1371bd 100644 --- a/crates/bevy_gizmos/src/pipeline_2d.rs +++ b/crates/bevy_gizmos/src/pipeline_2d.rs @@ -1,3 +1,4 @@ +use crate::view::{OnlyViewLayout, SetViewBindGroup}; use crate::{ config::{GizmoLineJoint, GizmoLineStyle, GizmoMeshConfig}, line_gizmo_vertex_buffer_layouts, line_joint_gizmo_vertex_buffer_layouts, DrawLineGizmo, @@ -10,7 +11,7 @@ use bevy_core_pipeline::core_2d::{Transparent2d, CORE_2D_DEPTH_FORMAT}; use bevy_ecs::{ prelude::Entity, resource::Resource, - schedule::{IntoSystemConfigs, IntoSystemSetConfigs}, + schedule::IntoSystemConfigs, system::{Query, Res, ResMut}, world::{FromWorld, World}, }; @@ -25,9 +26,8 @@ use bevy_render::{ }, render_resource::*, view::{ExtractedView, Msaa, RenderLayers, ViewTarget}, - Render, RenderApp, RenderSet, + Render, RenderApp, }; -use bevy_sprite::{Mesh2dPipeline, Mesh2dPipelineKey, SetMesh2dViewBindGroup}; use tracing::error; pub struct LineGizmo2dPlugin; @@ -44,15 +44,6 @@ impl Plugin for LineGizmo2dPlugin { .add_render_command::() .init_resource::>() .init_resource::>() - .configure_sets( - Render, - GizmoRenderSystem::QueueLineGizmos2d - .in_set(RenderSet::Queue) - .ambiguous_with(bevy_sprite::queue_sprites) - .ambiguous_with( - bevy_sprite::queue_material2d_meshes::, - ), - ) .add_systems( Render, (queue_line_gizmos_2d, queue_line_joint_gizmos_2d) @@ -73,14 +64,15 @@ impl Plugin for LineGizmo2dPlugin { #[derive(Clone, Resource)] struct LineGizmoPipeline { - mesh_pipeline: Mesh2dPipeline, + view_layout: BindGroupLayout, uniform_layout: BindGroupLayout, } impl FromWorld for LineGizmoPipeline { fn from_world(render_world: &mut World) -> Self { + let view_layout = render_world.resource::().0.clone(); LineGizmoPipeline { - mesh_pipeline: render_world.resource::().clone(), + view_layout, uniform_layout: render_world .resource::() .layout @@ -91,7 +83,8 @@ impl FromWorld for LineGizmoPipeline { #[derive(PartialEq, Eq, Hash, Clone)] struct LineGizmoPipelineKey { - mesh_key: Mesh2dPipelineKey, + hdr: bool, + msaa: Msaa, strip: bool, line_style: GizmoLineStyle, } @@ -100,7 +93,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { type Key = LineGizmoPipelineKey; fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { - let format = if key.mesh_key.contains(Mesh2dPipelineKey::HDR) { + let format = if key.hdr { ViewTarget::TEXTURE_FORMAT_HDR } else { TextureFormat::bevy_default() @@ -111,10 +104,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { "SIXTEEN_BYTE_ALIGNMENT".into(), ]; - let layout = vec![ - self.mesh_pipeline.view_layout.clone(), - self.uniform_layout.clone(), - ]; + let layout = vec![self.view_layout.clone(), self.uniform_layout.clone()]; let fragment_entry_point = match key.line_style { GizmoLineStyle::Solid => "fragment_solid", @@ -158,7 +148,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { }, }), multisample: MultisampleState { - count: key.mesh_key.msaa_samples(), + count: key.msaa.samples(), mask: !0, alpha_to_coverage_enabled: false, }, @@ -171,14 +161,15 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { #[derive(Clone, Resource)] struct LineJointGizmoPipeline { - mesh_pipeline: Mesh2dPipeline, + view_layout: BindGroupLayout, uniform_layout: BindGroupLayout, } impl FromWorld for LineJointGizmoPipeline { fn from_world(render_world: &mut World) -> Self { + let view_layout = render_world.resource::().0.clone(); LineJointGizmoPipeline { - mesh_pipeline: render_world.resource::().clone(), + view_layout, uniform_layout: render_world .resource::() .layout @@ -189,7 +180,8 @@ impl FromWorld for LineJointGizmoPipeline { #[derive(PartialEq, Eq, Hash, Clone)] struct LineJointGizmoPipelineKey { - mesh_key: Mesh2dPipelineKey, + hdr: bool, + msaa: Msaa, joints: GizmoLineJoint, } @@ -197,7 +189,7 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline { type Key = LineJointGizmoPipelineKey; fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { - let format = if key.mesh_key.contains(Mesh2dPipelineKey::HDR) { + let format = if key.hdr { ViewTarget::TEXTURE_FORMAT_HDR } else { TextureFormat::bevy_default() @@ -208,10 +200,7 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline { "SIXTEEN_BYTE_ALIGNMENT".into(), ]; - let layout = vec![ - self.mesh_pipeline.view_layout.clone(), - self.uniform_layout.clone(), - ]; + let layout = vec![self.view_layout.clone(), self.uniform_layout.clone()]; if key.joints == GizmoLineJoint::None { error!("There is no entry point for line joints with GizmoLineJoints::None. Please consider aborting the drawing process before reaching this stage."); @@ -259,7 +248,7 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline { }, }), multisample: MultisampleState { - count: key.mesh_key.msaa_samples(), + count: key.msaa.samples(), mask: !0, alpha_to_coverage_enabled: false, }, @@ -272,19 +261,19 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline { type DrawLineGizmo2d = ( SetItemPipeline, - SetMesh2dViewBindGroup<0>, + SetViewBindGroup<0>, SetLineGizmoBindGroup<1>, DrawLineGizmo, ); type DrawLineGizmo2dStrip = ( SetItemPipeline, - SetMesh2dViewBindGroup<0>, + SetViewBindGroup<0>, SetLineGizmoBindGroup<1>, DrawLineGizmo, ); type DrawLineJointGizmo2d = ( SetItemPipeline, - SetMesh2dViewBindGroup<0>, + SetViewBindGroup<0>, SetLineGizmoBindGroup<1>, DrawLineJointGizmo, ); @@ -311,9 +300,6 @@ fn queue_line_gizmos_2d( continue; }; - let mesh_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples()) - | Mesh2dPipelineKey::from_hdr(view.hdr); - let render_layers = render_layers.unwrap_or_default(); for (entity, main_entity, config) in &line_gizmos { if !config.render_layers.intersects(render_layers) { @@ -329,7 +315,8 @@ fn queue_line_gizmos_2d( &pipeline_cache, &pipeline, LineGizmoPipelineKey { - mesh_key, + msaa: *msaa, + hdr: view.hdr, strip: false, line_style: config.line_style, }, @@ -350,7 +337,8 @@ fn queue_line_gizmos_2d( &pipeline_cache, &pipeline, LineGizmoPipelineKey { - mesh_key, + msaa: *msaa, + hdr: view.hdr, strip: true, line_style: config.line_style, }, @@ -389,9 +377,6 @@ fn queue_line_joint_gizmos_2d( continue; }; - let mesh_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples()) - | Mesh2dPipelineKey::from_hdr(view.hdr); - let render_layers = render_layers.unwrap_or_default(); for (entity, main_entity, config) in &line_gizmos { if !config.render_layers.intersects(render_layers) { @@ -410,7 +395,8 @@ fn queue_line_joint_gizmos_2d( &pipeline_cache, &pipeline, LineJointGizmoPipelineKey { - mesh_key, + msaa: *msaa, + hdr: view.hdr, joints: config.line_joints, }, ); diff --git a/crates/bevy_gizmos/src/pipeline_3d.rs b/crates/bevy_gizmos/src/pipeline_3d.rs index 51308965d1..9afa2f7b41 100644 --- a/crates/bevy_gizmos/src/pipeline_3d.rs +++ b/crates/bevy_gizmos/src/pipeline_3d.rs @@ -1,26 +1,22 @@ use crate::{ config::{GizmoLineJoint, GizmoLineStyle, GizmoMeshConfig}, - line_gizmo_vertex_buffer_layouts, line_joint_gizmo_vertex_buffer_layouts, DrawLineGizmo, - DrawLineJointGizmo, GizmoRenderSystem, GpuLineGizmo, LineGizmoUniformBindgroupLayout, - SetLineGizmoBindGroup, LINE_JOINT_SHADER_HANDLE, LINE_SHADER_HANDLE, + line_gizmo_vertex_buffer_layouts, line_joint_gizmo_vertex_buffer_layouts, + view::{prepare_view_bind_groups, OnlyViewLayout, SetViewBindGroup}, + DrawLineGizmo, DrawLineJointGizmo, GizmoRenderSystem, GpuLineGizmo, + LineGizmoUniformBindgroupLayout, SetLineGizmoBindGroup, LINE_JOINT_SHADER_HANDLE, + LINE_SHADER_HANDLE, }; use bevy_app::{App, Plugin}; -use bevy_core_pipeline::{ - core_3d::{Transparent3d, CORE_3D_DEPTH_FORMAT}, - oit::OrderIndependentTransparencySettings, - prepass::{DeferredPrepass, DepthPrepass, MotionVectorPrepass, NormalPrepass}, -}; +use bevy_core_pipeline::core_3d::{Transparent3d, CORE_3D_DEPTH_FORMAT}; +use bevy_ecs::schedule::IntoSystemConfigs; use bevy_ecs::{ prelude::Entity, - query::Has, resource::Resource, - schedule::{IntoSystemConfigs, IntoSystemSetConfigs}, system::{Query, Res, ResMut}, world::{FromWorld, World}, }; use bevy_image::BevyDefault as _; -use bevy_pbr::{MeshPipeline, MeshPipelineKey, SetMeshViewBindGroup}; use bevy_render::sync_world::MainEntity; use bevy_render::{ render_asset::{prepare_assets, RenderAssets}, @@ -33,7 +29,6 @@ use bevy_render::{ Render, RenderApp, RenderSet, }; use tracing::error; - pub struct LineGizmo3dPlugin; impl Plugin for LineGizmo3dPlugin { fn build(&self, app: &mut App) { @@ -47,15 +42,13 @@ impl Plugin for LineGizmo3dPlugin { .add_render_command::() .init_resource::>() .init_resource::>() - .configure_sets( - Render, - GizmoRenderSystem::QueueLineGizmos3d - .in_set(RenderSet::Queue) - .ambiguous_with(bevy_pbr::queue_material_meshes::), - ) .add_systems( Render, - (queue_line_gizmos_3d, queue_line_joint_gizmos_3d) + ( + queue_line_gizmos_3d, + queue_line_joint_gizmos_3d, + prepare_view_bind_groups.in_set(RenderSet::Prepare), + ) .in_set(GizmoRenderSystem::QueueLineGizmos3d) .after(prepare_assets::), ); @@ -72,15 +65,17 @@ impl Plugin for LineGizmo3dPlugin { } #[derive(Clone, Resource)] -struct LineGizmoPipeline { - mesh_pipeline: MeshPipeline, +pub(crate) struct LineGizmoPipeline { + view_layout: BindGroupLayout, uniform_layout: BindGroupLayout, } impl FromWorld for LineGizmoPipeline { fn from_world(render_world: &mut World) -> Self { + let view_layout = render_world.resource::().0.clone(); + LineGizmoPipeline { - mesh_pipeline: render_world.resource::().clone(), + view_layout, uniform_layout: render_world .resource::() .layout @@ -90,8 +85,9 @@ impl FromWorld for LineGizmoPipeline { } #[derive(PartialEq, Eq, Hash, Clone)] -struct LineGizmoPipelineKey { - view_key: MeshPipelineKey, +pub(crate) struct LineGizmoPipelineKey { + msaa: Msaa, + hdr: bool, strip: bool, perspective: bool, line_style: GizmoLineStyle, @@ -110,18 +106,13 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { shader_defs.push("PERSPECTIVE".into()); } - let format = if key.view_key.contains(MeshPipelineKey::HDR) { + let format = if key.hdr { ViewTarget::TEXTURE_FORMAT_HDR } else { TextureFormat::bevy_default() }; - let view_layout = self - .mesh_pipeline - .get_view_layout(key.view_key.into()) - .clone(); - - let layout = vec![view_layout, self.uniform_layout.clone()]; + let layout = vec![self.view_layout.clone(), self.uniform_layout.clone()]; let fragment_entry_point = match key.line_style { GizmoLineStyle::Solid => "fragment_solid", @@ -156,7 +147,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { bias: DepthBiasState::default(), }), multisample: MultisampleState { - count: key.view_key.msaa_samples(), + count: key.msaa.samples(), mask: !0, alpha_to_coverage_enabled: false, }, @@ -169,14 +160,16 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { #[derive(Clone, Resource)] struct LineJointGizmoPipeline { - mesh_pipeline: MeshPipeline, + view_layout: BindGroupLayout, uniform_layout: BindGroupLayout, } impl FromWorld for LineJointGizmoPipeline { fn from_world(render_world: &mut World) -> Self { + let view_layout = render_world.resource::().0.clone(); + LineJointGizmoPipeline { - mesh_pipeline: render_world.resource::().clone(), + view_layout, uniform_layout: render_world .resource::() .layout @@ -187,7 +180,8 @@ impl FromWorld for LineJointGizmoPipeline { #[derive(PartialEq, Eq, Hash, Clone)] struct LineJointGizmoPipelineKey { - view_key: MeshPipelineKey, + msaa: Msaa, + hdr: bool, perspective: bool, joints: GizmoLineJoint, } @@ -205,18 +199,13 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline { shader_defs.push("PERSPECTIVE".into()); } - let format = if key.view_key.contains(MeshPipelineKey::HDR) { + let format = if key.hdr { ViewTarget::TEXTURE_FORMAT_HDR } else { TextureFormat::bevy_default() }; - let view_layout = self - .mesh_pipeline - .get_view_layout(key.view_key.into()) - .clone(); - - let layout = vec![view_layout, self.uniform_layout.clone()]; + let layout = vec![self.view_layout.clone(), self.uniform_layout.clone()]; if key.joints == GizmoLineJoint::None { error!("There is no entry point for line joints with GizmoLineJoints::None. Please consider aborting the drawing process before reaching this stage."); @@ -255,7 +244,7 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline { bias: DepthBiasState::default(), }), multisample: MultisampleState { - count: key.view_key.msaa_samples(), + count: key.msaa.samples(), mask: !0, alpha_to_coverage_enabled: false, }, @@ -268,19 +257,19 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline { type DrawLineGizmo3d = ( SetItemPipeline, - SetMeshViewBindGroup<0>, + SetViewBindGroup<0>, SetLineGizmoBindGroup<1>, DrawLineGizmo, ); type DrawLineGizmo3dStrip = ( SetItemPipeline, - SetMeshViewBindGroup<0>, + SetViewBindGroup<0>, SetLineGizmoBindGroup<1>, DrawLineGizmo, ); type DrawLineJointGizmo3d = ( SetItemPipeline, - SetMeshViewBindGroup<0>, + SetViewBindGroup<0>, SetLineGizmoBindGroup<1>, DrawLineJointGizmo, ); @@ -293,18 +282,7 @@ fn queue_line_gizmos_3d( line_gizmos: Query<(Entity, &MainEntity, &GizmoMeshConfig)>, line_gizmo_assets: Res>, mut transparent_render_phases: ResMut>, - views: Query<( - &ExtractedView, - &Msaa, - Option<&RenderLayers>, - ( - Has, - Has, - Has, - Has, - Has, - ), - )>, + views: Query<(&ExtractedView, &Msaa, Option<&RenderLayers>)>, ) { let draw_function = draw_functions.read().get_id::().unwrap(); let draw_function_strip = draw_functions @@ -312,13 +290,7 @@ fn queue_line_gizmos_3d( .get_id::() .unwrap(); - for ( - view, - msaa, - render_layers, - (normal_prepass, depth_prepass, motion_vector_prepass, deferred_prepass, oit), - ) in &views - { + for (view, msaa, render_layers) in &views { let Some(transparent_phase) = transparent_render_phases.get_mut(&view.retained_view_entity) else { continue; @@ -326,29 +298,6 @@ fn queue_line_gizmos_3d( let render_layers = render_layers.unwrap_or_default(); - let mut view_key = MeshPipelineKey::from_msaa_samples(msaa.samples()) - | MeshPipelineKey::from_hdr(view.hdr); - - if normal_prepass { - view_key |= MeshPipelineKey::NORMAL_PREPASS; - } - - if depth_prepass { - view_key |= MeshPipelineKey::DEPTH_PREPASS; - } - - if motion_vector_prepass { - view_key |= MeshPipelineKey::MOTION_VECTOR_PREPASS; - } - - if deferred_prepass { - view_key |= MeshPipelineKey::DEFERRED_PREPASS; - } - - if oit { - view_key |= MeshPipelineKey::OIT_ENABLED; - } - for (entity, main_entity, config) in &line_gizmos { if !config.render_layers.intersects(render_layers) { continue; @@ -363,7 +312,8 @@ fn queue_line_gizmos_3d( &pipeline_cache, &pipeline, LineGizmoPipelineKey { - view_key, + msaa: *msaa, + hdr: view.hdr, strip: false, perspective: config.line_perspective, line_style: config.line_style, @@ -385,7 +335,8 @@ fn queue_line_gizmos_3d( &pipeline_cache, &pipeline, LineGizmoPipelineKey { - view_key, + msaa: *msaa, + hdr: view.hdr, strip: true, perspective: config.line_perspective, line_style: config.line_style, @@ -413,30 +364,14 @@ fn queue_line_joint_gizmos_3d( line_gizmos: Query<(Entity, &MainEntity, &GizmoMeshConfig)>, line_gizmo_assets: Res>, mut transparent_render_phases: ResMut>, - views: Query<( - &ExtractedView, - &Msaa, - Option<&RenderLayers>, - ( - Has, - Has, - Has, - Has, - ), - )>, + mut views: Query<(&ExtractedView, &Msaa, Option<&RenderLayers>)>, ) { let draw_function = draw_functions .read() .get_id::() .unwrap(); - for ( - view, - msaa, - render_layers, - (normal_prepass, depth_prepass, motion_vector_prepass, deferred_prepass), - ) in &views - { + for (view, msaa, render_layers) in &mut views { let Some(transparent_phase) = transparent_render_phases.get_mut(&view.retained_view_entity) else { continue; @@ -444,25 +379,6 @@ fn queue_line_joint_gizmos_3d( let render_layers = render_layers.unwrap_or_default(); - let mut view_key = MeshPipelineKey::from_msaa_samples(msaa.samples()) - | MeshPipelineKey::from_hdr(view.hdr); - - if normal_prepass { - view_key |= MeshPipelineKey::NORMAL_PREPASS; - } - - if depth_prepass { - view_key |= MeshPipelineKey::DEPTH_PREPASS; - } - - if motion_vector_prepass { - view_key |= MeshPipelineKey::MOTION_VECTOR_PREPASS; - } - - if deferred_prepass { - view_key |= MeshPipelineKey::DEFERRED_PREPASS; - } - for (entity, main_entity, config) in &line_gizmos { if !config.render_layers.intersects(render_layers) { continue; @@ -480,7 +396,8 @@ fn queue_line_joint_gizmos_3d( &pipeline_cache, &pipeline, LineJointGizmoPipelineKey { - view_key, + msaa: *msaa, + hdr: view.hdr, perspective: config.line_perspective, joints: config.line_joints, }, diff --git a/crates/bevy_gizmos/src/retained.rs b/crates/bevy_gizmos/src/retained.rs index 51170144b1..cf3785179a 100644 --- a/crates/bevy_gizmos/src/retained.rs +++ b/crates/bevy_gizmos/src/retained.rs @@ -143,7 +143,6 @@ pub(crate) fn extract_linegizmos( #[cfg(feature = "webgl")] _padding: Default::default(), }, - #[cfg(any(feature = "bevy_pbr", feature = "bevy_sprite"))] crate::config::GizmoMeshConfig { line_perspective: gizmo.line_config.perspective, line_style: gizmo.line_config.style, diff --git a/crates/bevy_gizmos/src/view.rs b/crates/bevy_gizmos/src/view.rs new file mode 100644 index 0000000000..34fa94c6c5 --- /dev/null +++ b/crates/bevy_gizmos/src/view.rs @@ -0,0 +1,90 @@ +use bevy_ecs::{ + component::Component, + entity::Entity, + query::With, + resource::Resource, + system::{lifetimeless::Read, Commands, Query, Res}, + world::FromWorld, +}; +use bevy_render::{ + render_phase::{PhaseItem, RenderCommand, RenderCommandResult}, + render_resource::{ + binding_types::uniform_buffer, BindGroup, BindGroupLayout, BindGroupLayoutEntry, + DynamicBindGroupEntries, DynamicBindGroupLayoutEntries, ShaderStages, + }, + renderer::RenderDevice, + view::{ExtractedView, ViewUniform, ViewUniforms}, +}; + +#[derive(Component)] +pub(crate) struct ViewBindGroup(BindGroup); + +/// very common layout: just the view uniform +#[derive(Resource)] +pub(crate) struct OnlyViewLayout(pub BindGroupLayout); + +impl FromWorld for OnlyViewLayout { + fn from_world(world: &mut bevy_ecs::world::World) -> Self { + let render_device = world.resource::(); + + let view_layout = + render_device.create_bind_group_layout("mesh_view_layout", &view_layout_entries()); + + Self(view_layout) + } +} + +pub(crate) struct SetViewBindGroup; + +impl RenderCommand

for SetViewBindGroup { + type Param = (); + + type ViewQuery = Read; + + type ItemQuery = (); + + fn render<'w>( + _: &P, + view: bevy_ecs::query::ROQueryItem<'w, Self::ViewQuery>, + _: Option>, + _: bevy_ecs::system::SystemParamItem<'w, '_, Self::Param>, + pass: &mut bevy_render::render_phase::TrackedRenderPass<'w>, + ) -> RenderCommandResult { + pass.set_bind_group(I, &view.0, &[0]); + RenderCommandResult::Success + } +} + +pub(crate) fn prepare_view_bind_groups( + mut commands: Commands, + render_device: Res, + view_uniforms: Res, + layout: Res, + views: Query>, +) { + let Some(view_binding) = view_uniforms.uniforms.binding() else { + return; + }; + + let entries = DynamicBindGroupEntries::new_with_indices(((0, view_binding.clone()),)); + for entity in &views { + commands + .entity(entity) + .insert(ViewBindGroup(render_device.create_bind_group( + "view_bind_group", + &layout.0, + &entries, + ))); + } +} + +pub(crate) fn view_layout_entries() -> Vec { + DynamicBindGroupLayoutEntries::new_with_indices( + ShaderStages::FRAGMENT, + (( + 0, + uniform_buffer::(true).visibility(ShaderStages::VERTEX_FRAGMENT), + ),), + ) + .to_vec() +} diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index b0be2f00c8..073de918bd 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -172,7 +172,7 @@ bevy_ci_testing = ["bevy_dev_tools/bevy_ci_testing", "bevy_render?/ci_limits"] # Enable animation support, and glTF animation loading animation = ["bevy_animation", "bevy_gltf?/bevy_animation"] -bevy_sprite = ["dep:bevy_sprite", "bevy_gizmos?/bevy_sprite", "bevy_image"] +bevy_sprite = ["dep:bevy_sprite", "bevy_gizmos", "bevy_image"] bevy_pbr = ["dep:bevy_pbr", "bevy_gizmos?/bevy_pbr", "bevy_image"] bevy_window = ["dep:bevy_window", "dep:bevy_a11y"] bevy_core_pipeline = ["dep:bevy_core_pipeline", "bevy_image"]