mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 06:00:20 +00:00
Fix CameraProjection
panic and improve CameraProjectionPlugin
(#11808)
# Objective Fix https://github.com/bevyengine/bevy/issues/11799 and improve `CameraProjectionPlugin` ## Solution `CameraProjectionPlugin` is now an all-in-one plugin for adding a custom `CameraProjection`. I also added `PbrProjectionPlugin` which is like `CameraProjectionPlugin` but for PBR. P.S. I'd like to get this merged after https://github.com/bevyengine/bevy/pull/11766. --- ## Changelog - Changed `CameraProjectionPlugin` to be an all-in-one plugin for adding a `CameraProjection` - Removed `VisibilitySystems::{UpdateOrthographicFrusta, UpdatePerspectiveFrusta, UpdateProjectionFrusta}`, now replaced with `VisibilitySystems::UpdateFrusta` - Added `PbrProjectionPlugin` for projection-specific PBR functionality. ## Migration Guide `VisibilitySystems`'s `UpdateOrthographicFrusta`, `UpdatePerspectiveFrusta`, and `UpdateProjectionFrusta` variants were removed, they were replaced with `VisibilitySystems::UpdateFrusta`
This commit is contained in:
parent
75f1c5df7d
commit
de9dc9c204
3 changed files with 53 additions and 50 deletions
|
@ -36,6 +36,8 @@ mod render;
|
|||
mod ssao;
|
||||
|
||||
use bevy_color::{Color, LinearRgba};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub use bundle::*;
|
||||
pub use extended_material::*;
|
||||
pub use fog::*;
|
||||
|
@ -91,7 +93,10 @@ use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d};
|
|||
use bevy_ecs::prelude::*;
|
||||
use bevy_render::{
|
||||
alpha::AlphaMode,
|
||||
camera::{CameraUpdateSystem, Projection},
|
||||
camera::{
|
||||
CameraProjection, CameraUpdateSystem, OrthographicProjection, PerspectiveProjection,
|
||||
Projection,
|
||||
},
|
||||
extract_component::ExtractComponentPlugin,
|
||||
extract_resource::ExtractResourcePlugin,
|
||||
render_asset::prepare_assets,
|
||||
|
@ -303,6 +308,9 @@ impl Plugin for PbrPlugin {
|
|||
ExtractComponentPlugin::<ShadowFilteringMethod>::default(),
|
||||
LightmapPlugin,
|
||||
LightProbePlugin,
|
||||
PbrProjectionPlugin::<Projection>::default(),
|
||||
PbrProjectionPlugin::<PerspectiveProjection>::default(),
|
||||
PbrProjectionPlugin::<OrthographicProjection>::default(),
|
||||
GpuMeshPreprocessPlugin {
|
||||
use_gpu_instance_buffer_builder: self.use_gpu_instance_buffer_builder,
|
||||
},
|
||||
|
@ -324,11 +332,7 @@ impl Plugin for PbrPlugin {
|
|||
.after(TransformSystem::TransformPropagate)
|
||||
.after(VisibilitySystems::CheckVisibility)
|
||||
.after(CameraUpdateSystem),
|
||||
(
|
||||
clear_directional_light_cascades,
|
||||
build_directional_light_cascades::<Projection>,
|
||||
)
|
||||
.chain()
|
||||
clear_directional_light_cascades
|
||||
.in_set(SimulationLightSystems::UpdateDirectionalLightCascades)
|
||||
.after(TransformSystem::TransformPropagate)
|
||||
.after(CameraUpdateSystem),
|
||||
|
@ -414,3 +418,21 @@ impl Plugin for PbrPlugin {
|
|||
.init_resource::<GlobalLightMeta>();
|
||||
}
|
||||
}
|
||||
|
||||
/// [`CameraProjection`] specific PBR functionality.
|
||||
pub struct PbrProjectionPlugin<T: CameraProjection + Component>(PhantomData<T>);
|
||||
impl<T: CameraProjection + Component> Plugin for PbrProjectionPlugin<T> {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(
|
||||
PostUpdate,
|
||||
build_directional_light_cascades::<T>
|
||||
.in_set(SimulationLightSystems::UpdateDirectionalLightCascades)
|
||||
.after(clear_directional_light_cascades),
|
||||
);
|
||||
}
|
||||
}
|
||||
impl<T: CameraProjection + Component> Default for PbrProjectionPlugin<T> {
|
||||
fn default() -> Self {
|
||||
Self(Default::default())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::marker::PhantomData;
|
|||
use std::ops::{Div, DivAssign, Mul, MulAssign};
|
||||
|
||||
use crate::primitives::Frustum;
|
||||
use crate::view::VisibilitySystems;
|
||||
use bevy_app::{App, Plugin, PostStartup, PostUpdate};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_math::{AspectRatio, Mat4, Rect, Vec2, Vec3A};
|
||||
|
@ -9,9 +10,12 @@ use bevy_reflect::{
|
|||
std_traits::ReflectDefault, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize,
|
||||
};
|
||||
use bevy_transform::components::GlobalTransform;
|
||||
use bevy_transform::TransformSystem;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Adds [`Camera`](crate::camera::Camera) driver systems for a given projection type.
|
||||
///
|
||||
/// If you are using `bevy_pbr`, then you need to add `PbrProjectionPlugin` along with this.
|
||||
pub struct CameraProjectionPlugin<T: CameraProjection + Component + GetTypeRegistration>(
|
||||
PhantomData<T>,
|
||||
);
|
||||
|
@ -29,12 +33,22 @@ impl<T: CameraProjection + Component + GetTypeRegistration> Plugin for CameraPro
|
|||
)
|
||||
.add_systems(
|
||||
PostUpdate,
|
||||
crate::camera::camera_system::<T>
|
||||
.in_set(CameraUpdateSystem)
|
||||
// We assume that each camera will only have one projection,
|
||||
// so we can ignore ambiguities with all other monomorphizations.
|
||||
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||
.ambiguous_with(CameraUpdateSystem),
|
||||
(
|
||||
crate::camera::camera_system::<T>
|
||||
.in_set(CameraUpdateSystem)
|
||||
// We assume that each camera will only have one projection,
|
||||
// so we can ignore ambiguities with all other monomorphizations.
|
||||
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||
.ambiguous_with(CameraUpdateSystem),
|
||||
crate::view::update_frusta::<T>
|
||||
.in_set(VisibilitySystems::UpdateFrusta)
|
||||
.after(crate::camera::camera_system::<T>)
|
||||
.after(TransformSystem::TransformPropagate)
|
||||
// We assume that no camera will have more than one projection component,
|
||||
// so these systems will run independently of one another.
|
||||
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||
.ambiguous_with(VisibilitySystems::UpdateFrusta),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,7 @@ use bevy_transform::{components::GlobalTransform, TransformSystem};
|
|||
use bevy_utils::{Parallel, TypeIdMap};
|
||||
|
||||
use crate::{
|
||||
camera::{
|
||||
camera_system, Camera, CameraProjection, OrthographicProjection, PerspectiveProjection,
|
||||
Projection,
|
||||
},
|
||||
camera::{Camera, CameraProjection},
|
||||
mesh::Mesh,
|
||||
primitives::{Aabb, Frustum, Sphere},
|
||||
};
|
||||
|
@ -239,12 +236,8 @@ pub enum VisibilitySystems {
|
|||
/// Label for the [`calculate_bounds`], `calculate_bounds_2d` and `calculate_bounds_text2d` systems,
|
||||
/// calculating and inserting an [`Aabb`] to relevant entities.
|
||||
CalculateBounds,
|
||||
/// Label for the [`update_frusta<OrthographicProjection>`] system.
|
||||
UpdateOrthographicFrusta,
|
||||
/// Label for the [`update_frusta<PerspectiveProjection>`] system.
|
||||
UpdatePerspectiveFrusta,
|
||||
/// Label for the [`update_frusta<Projection>`] system.
|
||||
UpdateProjectionFrusta,
|
||||
/// Label for [`update_frusta`] in [`CameraProjectionPlugin`](crate::camera::CameraProjectionPlugin).
|
||||
UpdateFrusta,
|
||||
/// Label for the system propagating the [`InheritedVisibility`] in a
|
||||
/// [`hierarchy`](bevy_hierarchy).
|
||||
VisibilityPropagate,
|
||||
|
@ -261,13 +254,7 @@ impl Plugin for VisibilityPlugin {
|
|||
|
||||
app.configure_sets(
|
||||
PostUpdate,
|
||||
(
|
||||
CalculateBounds,
|
||||
UpdateOrthographicFrusta,
|
||||
UpdatePerspectiveFrusta,
|
||||
UpdateProjectionFrusta,
|
||||
VisibilityPropagate,
|
||||
)
|
||||
(CalculateBounds, UpdateFrusta, VisibilityPropagate)
|
||||
.before(CheckVisibility)
|
||||
.after(TransformSystem::TransformPropagate),
|
||||
)
|
||||
|
@ -275,24 +262,6 @@ impl Plugin for VisibilityPlugin {
|
|||
PostUpdate,
|
||||
(
|
||||
calculate_bounds.in_set(CalculateBounds),
|
||||
update_frusta::<OrthographicProjection>
|
||||
.in_set(UpdateOrthographicFrusta)
|
||||
.after(camera_system::<OrthographicProjection>)
|
||||
// We assume that no camera will have more than one projection component,
|
||||
// so these systems will run independently of one another.
|
||||
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||
.ambiguous_with(update_frusta::<PerspectiveProjection>)
|
||||
.ambiguous_with(update_frusta::<Projection>),
|
||||
update_frusta::<PerspectiveProjection>
|
||||
.in_set(UpdatePerspectiveFrusta)
|
||||
.after(camera_system::<PerspectiveProjection>)
|
||||
// We assume that no camera will have more than one projection component,
|
||||
// so these systems will run independently of one another.
|
||||
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||
.ambiguous_with(update_frusta::<Projection>),
|
||||
update_frusta::<Projection>
|
||||
.in_set(UpdateProjectionFrusta)
|
||||
.after(camera_system::<Projection>),
|
||||
(visibility_propagate_system, reset_view_visibility).in_set(VisibilityPropagate),
|
||||
check_visibility::<WithMesh>.in_set(CheckVisibility),
|
||||
),
|
||||
|
@ -320,9 +289,7 @@ pub fn calculate_bounds(
|
|||
|
||||
/// Updates [`Frustum`].
|
||||
///
|
||||
/// This system is used in system sets [`VisibilitySystems::UpdateProjectionFrusta`],
|
||||
/// [`VisibilitySystems::UpdatePerspectiveFrusta`], and
|
||||
/// [`VisibilitySystems::UpdateOrthographicFrusta`].
|
||||
/// This system is used in [`CameraProjectionPlugin`](crate::camera::CameraProjectionPlugin).
|
||||
pub fn update_frusta<T: Component + CameraProjection + Send + Sync + 'static>(
|
||||
mut views: Query<
|
||||
(&GlobalTransform, &T, &mut Frustum),
|
||||
|
|
Loading…
Reference in a new issue