From 1b09c4051e0417b85d53a11cc23cea872c66caec Mon Sep 17 00:00:00 2001 From: atlv Date: Sat, 5 Jul 2025 09:24:28 -0400 Subject: [PATCH] Move Camera3d/2d to bevy_camera (#19953) # Objective - define scenes without bevy_render ## Solution - Move Camera2d/3d components out of bevy_core_pipeline ## Testing - 3d_scene runs fine Note: no breaking changes thanks to re-exports --- .../src/components.rs} | 38 ++++++++----------- crates/bevy_camera/src/lib.rs | 2 + crates/bevy_core_pipeline/Cargo.toml | 1 + .../src/core_2d/camera_2d.rs | 26 ------------- crates/bevy_core_pipeline/src/core_2d/mod.rs | 14 +++++-- crates/bevy_core_pipeline/src/core_3d/mod.rs | 13 +++++-- crates/bevy_render/src/camera.rs | 28 +++++++++++--- 7 files changed, 63 insertions(+), 59 deletions(-) rename crates/{bevy_core_pipeline/src/core_3d/camera_3d.rs => bevy_camera/src/components.rs} (87%) delete mode 100644 crates/bevy_core_pipeline/src/core_2d/camera_2d.rs diff --git a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs b/crates/bevy_camera/src/components.rs similarity index 87% rename from crates/bevy_core_pipeline/src/core_3d/camera_3d.rs rename to crates/bevy_camera/src/components.rs index f5314c736d..867936727c 100644 --- a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs +++ b/crates/bevy_camera/src/components.rs @@ -1,39 +1,33 @@ -use crate::{ - core_3d::graph::Core3d, - tonemapping::{DebandDither, Tonemapping}, -}; +use crate::{primitives::Frustum, Camera, CameraProjection, OrthographicProjection, Projection}; use bevy_ecs::prelude::*; use bevy_reflect::{std_traits::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize}; -use bevy_render::{ - camera::{Camera, CameraRenderGraph, Exposure, Projection}, - extract_component::ExtractComponent, - render_resource::{LoadOp, TextureUsages}, - view::ColorGrading, -}; +use bevy_transform::prelude::{GlobalTransform, Transform}; use serde::{Deserialize, Serialize}; +use wgpu_types::{LoadOp, TextureUsages}; + +/// A 2D camera component. Enables the 2D render graph for a [`Camera`]. +#[derive(Component, Default, Reflect, Clone)] +#[reflect(Component, Default, Clone)] +#[require( + Camera, + Projection::Orthographic(OrthographicProjection::default_2d()), + Frustum = OrthographicProjection::default_2d().compute_frustum(&GlobalTransform::from(Transform::default())), +)] +pub struct Camera2d; /// A 3D camera component. Enables the main 3D render graph for a [`Camera`]. /// /// The camera coordinate space is right-handed X-right, Y-up, Z-back. /// This means "forward" is -Z. -#[derive(Component, Reflect, Clone, ExtractComponent)] -#[extract_component_filter(With)] +#[derive(Component, Reflect, Clone)] #[reflect(Component, Default, Clone)] -#[require( - Camera, - DebandDither::Enabled, - CameraRenderGraph::new(Core3d), - Projection, - Tonemapping, - ColorGrading, - Exposure -)] +#[require(Camera, Projection)] pub struct Camera3d { /// The depth clear operation to perform for the main 3d pass. pub depth_load_op: Camera3dDepthLoadOp, /// The texture usages for the depth texture created for the main 3d pass. pub depth_texture_usages: Camera3dDepthTextureUsage, - /// How many individual steps should be performed in the [`Transmissive3d`](crate::core_3d::Transmissive3d) pass. + /// How many individual steps should be performed in the `Transmissive3d` pass. /// /// Roughly corresponds to how many “layers of transparency” are rendered for screen space /// specular transmissive objects. Each step requires making one additional diff --git a/crates/bevy_camera/src/lib.rs b/crates/bevy_camera/src/lib.rs index 6fd284d49d..bf0ededae8 100644 --- a/crates/bevy_camera/src/lib.rs +++ b/crates/bevy_camera/src/lib.rs @@ -1,12 +1,14 @@ #![expect(missing_docs, reason = "Not all docs are written yet, see #3492.")] mod camera; mod clear_color; +mod components; pub mod primitives; mod projection; pub mod visibility; pub use camera::*; pub use clear_color::*; +pub use components::*; pub use projection::*; use bevy_app::{App, Plugin}; diff --git a/crates/bevy_core_pipeline/Cargo.toml b/crates/bevy_core_pipeline/Cargo.toml index 9b3f158af2..680d57efa1 100644 --- a/crates/bevy_core_pipeline/Cargo.toml +++ b/crates/bevy_core_pipeline/Cargo.toml @@ -27,6 +27,7 @@ bevy_derive = { path = "../bevy_derive", version = "0.17.0-dev" } bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.17.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.17.0-dev" } bevy_image = { path = "../bevy_image", version = "0.17.0-dev" } +bevy_camera = { path = "../bevy_camera", version = "0.17.0-dev" } bevy_reflect = { path = "../bevy_reflect", version = "0.17.0-dev" } bevy_render = { path = "../bevy_render", version = "0.17.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.17.0-dev" } diff --git a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs deleted file mode 100644 index d46174192b..0000000000 --- a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::{ - core_2d::graph::Core2d, - tonemapping::{DebandDither, Tonemapping}, -}; -use bevy_ecs::prelude::*; -use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::{ - camera::{Camera, CameraProjection, CameraRenderGraph, OrthographicProjection, Projection}, - extract_component::ExtractComponent, - primitives::Frustum, -}; -use bevy_transform::prelude::{GlobalTransform, Transform}; - -/// A 2D camera component. Enables the 2D render graph for a [`Camera`]. -#[derive(Component, Default, Reflect, Clone, ExtractComponent)] -#[extract_component_filter(With)] -#[reflect(Component, Default, Clone)] -#[require( - Camera, - DebandDither, - CameraRenderGraph::new(Core2d), - Projection::Orthographic(OrthographicProjection::default_2d()), - Frustum = OrthographicProjection::default_2d().compute_frustum(&GlobalTransform::from(Transform::default())), - Tonemapping::None, -)] -pub struct Camera2d; diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index f50d3e5984..f051c1164c 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -1,4 +1,3 @@ -mod camera_2d; mod main_opaque_pass_2d_node; mod main_transparent_pass_2d_node; @@ -34,18 +33,22 @@ pub mod graph { use core::ops::Range; use bevy_asset::UntypedAssetId; +pub use bevy_camera::Camera2d; use bevy_image::ToExtents; use bevy_platform::collections::{HashMap, HashSet}; use bevy_render::{ batching::gpu_preprocessing::GpuPreprocessingMode, + camera::CameraRenderGraph, render_phase::PhaseItemBatchSetKey, view::{ExtractedView, RetainedViewEntity}, }; -pub use camera_2d::*; pub use main_opaque_pass_2d_node::*; pub use main_transparent_pass_2d_node::*; -use crate::{tonemapping::TonemappingNode, upscaling::UpscalingNode}; +use crate::{ + tonemapping::{DebandDither, Tonemapping, TonemappingNode}, + upscaling::UpscalingNode, +}; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; use bevy_math::FloatOrd; @@ -78,6 +81,11 @@ pub struct Core2dPlugin; impl Plugin for Core2dPlugin { fn build(&self, app: &mut App) { app.register_type::() + .register_required_components::() + .register_required_components_with::(|| { + CameraRenderGraph::new(Core2d) + }) + .register_required_components_with::(|| Tonemapping::None) .add_plugins(ExtractComponentPlugin::::default()); let Some(render_app) = app.get_sub_app_mut(RenderApp) else { diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 3a127631cc..9fd7880869 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -1,4 +1,3 @@ -mod camera_3d; mod main_opaque_pass_3d_node; mod main_transmissive_pass_3d_node; mod main_transparent_pass_3d_node; @@ -70,14 +69,17 @@ pub const DEPTH_TEXTURE_SAMPLING_SUPPORTED: bool = true; use core::ops::Range; +pub use bevy_camera::{ + Camera3d, Camera3dDepthLoadOp, Camera3dDepthTextureUsage, ScreenSpaceTransmissionQuality, +}; use bevy_render::{ batching::gpu_preprocessing::{GpuPreprocessingMode, GpuPreprocessingSupport}, + camera::CameraRenderGraph, experimental::occlusion_culling::OcclusionCulling, mesh::allocator::SlabId, render_phase::PhaseItemBatchSetKey, view::{prepare_view_targets, NoIndirectDrawing, RetainedViewEntity}, }; -pub use camera_3d::*; pub use main_opaque_pass_3d_node::*; pub use main_transparent_pass_3d_node::*; @@ -127,7 +129,7 @@ use crate::{ ViewPrepassTextures, MOTION_VECTOR_PREPASS_FORMAT, NORMAL_PREPASS_FORMAT, }, skybox::SkyboxPlugin, - tonemapping::TonemappingNode, + tonemapping::{DebandDither, Tonemapping, TonemappingNode}, upscaling::UpscalingNode, }; @@ -139,6 +141,11 @@ impl Plugin for Core3dPlugin { fn build(&self, app: &mut App) { app.register_type::() .register_type::() + .register_required_components_with::(|| DebandDither::Enabled) + .register_required_components_with::(|| { + CameraRenderGraph::new(Core3d) + }) + .register_required_components::() .add_plugins((SkyboxPlugin, ExtractComponentPlugin::::default())) .add_systems(PostUpdate, check_msaa); diff --git a/crates/bevy_render/src/camera.rs b/crates/bevy_render/src/camera.rs index b5dcc6baa5..346762aecc 100644 --- a/crates/bevy_render/src/camera.rs +++ b/crates/bevy_render/src/camera.rs @@ -29,7 +29,7 @@ use bevy_ecs::{ event::EventReader, lifecycle::HookContext, prelude::With, - query::Has, + query::{Has, QueryItem}, reflect::ReflectComponent, resource::Resource, schedule::IntoScheduleConfigs, @@ -59,6 +59,8 @@ impl Plugin for CameraPlugin { .register_type::() .register_required_components::() .register_required_components::() + .register_required_components::() + .register_required_components::() .add_plugins(( ExtractResourcePlugin::::default(), ExtractComponentPlugin::::default(), @@ -95,7 +97,7 @@ fn warn_on_no_render_graph(world: DeferredWorld, HookContext { entity, caller, . } impl ExtractResource for ClearColor { - type Source = ClearColor; + type Source = Self; fn extract_resource(source: &Self::Source) -> Self { source.clone() @@ -106,12 +108,28 @@ impl ExtractComponent for CameraMainTextureUsages { type QueryFilter = (); type Out = Self; - fn extract_component( - item: bevy_ecs::query::QueryItem<'_, '_, Self::QueryData>, - ) -> Option { + fn extract_component(item: QueryItem) -> Option { Some(*item) } } +impl ExtractComponent for Camera2d { + type QueryData = &'static Self; + type QueryFilter = With; + type Out = Self; + + fn extract_component(item: QueryItem) -> Option { + Some(item.clone()) + } +} +impl ExtractComponent for Camera3d { + type QueryData = &'static Self; + type QueryFilter = With; + type Out = Self; + + fn extract_component(item: QueryItem) -> Option { + Some(item.clone()) + } +} /// Configures the [`RenderGraph`] name assigned to be run for a given [`Camera`] entity. #[derive(Component, Debug, Deref, DerefMut, Reflect, Clone)]