Split OrthographicProjection::default into 2d & 3d (Adopted) (#15073)
Adopted PR from dmlary, all credit to them! https://github.com/bevyengine/bevy/pull/9915 Original description: # Objective The default value for `near` in `OrthographicProjection` should be different for 2d & 3d. For 2d using `near = -1000` allows bevy users to build up scenes using background `z = 0`, and foreground elements `z > 0` similar to css. However in 3d `near = -1000` results in objects behind the camera being rendered. Using `near = 0` works for 3d, but forces 2d users to assign `z <= 0` for rendered elements, putting the background at some arbitrary negative value. There is no common value for `near` that doesn't result in a footgun or usability issue for either 2d or 3d, so they should have separate values. There was discussion about other options in the discord [0](https://discord.com/channels/691052431525675048/1154114310042292325), but splitting `default()` into `default_2d()` and `default_3d()` seemed like the lowest cost approach. Related/past work https://github.com/bevyengine/bevy/issues/9138, https://github.com/bevyengine/bevy/pull/9214, https://github.com/bevyengine/bevy/pull/9310, https://github.com/bevyengine/bevy/pull/9537 (thanks to @Selene-Amanita for the list) ## Solution This commit splits `OrthographicProjection::default` into `default_2d` and `default_3d`. ## Migration Guide - In initialization of `OrthographicProjection`, change `..default()` to `..OrthographicProjection::default_2d()` or `..OrthographicProjection::default_3d()` Example: ```diff --- a/examples/3d/orthographic.rs +++ b/examples/3d/orthographic.rs @@ -20,7 +20,7 @@ fn setup( projection: OrthographicProjection { scale: 3.0, scaling_mode: ScalingMode::FixedVertical(2.0), - ..default() + ..OrthographicProjection::default_3d() } .into(), transform: Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y), ``` --------- Co-authored-by: David M. Lary <dmlary@gmail.com> Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
This commit is contained in:
parent
8460cfa6ab
commit
82e416dc48
@ -23,10 +23,6 @@ pub struct Camera2d;
|
|||||||
pub struct Camera2dBundle {
|
pub struct Camera2dBundle {
|
||||||
pub camera: Camera,
|
pub camera: Camera,
|
||||||
pub camera_render_graph: CameraRenderGraph,
|
pub camera_render_graph: CameraRenderGraph,
|
||||||
/// Note: default value for `OrthographicProjection.near` is `0.0`
|
|
||||||
/// which makes objects on the screen plane invisible to 2D camera.
|
|
||||||
/// `Camera2dBundle::default()` sets `near` to negative value,
|
|
||||||
/// so be careful when initializing this field manually.
|
|
||||||
pub projection: OrthographicProjection,
|
pub projection: OrthographicProjection,
|
||||||
pub visible_entities: VisibleEntities,
|
pub visible_entities: VisibleEntities,
|
||||||
pub frustum: Frustum,
|
pub frustum: Frustum,
|
||||||
@ -41,11 +37,7 @@ pub struct Camera2dBundle {
|
|||||||
|
|
||||||
impl Default for Camera2dBundle {
|
impl Default for Camera2dBundle {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let projection = OrthographicProjection {
|
let projection = OrthographicProjection::default_2d();
|
||||||
far: 1000.,
|
|
||||||
near: -1000.,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let transform = Transform::default();
|
let transform = Transform::default();
|
||||||
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
|
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
|
||||||
Self {
|
Self {
|
||||||
@ -77,7 +69,7 @@ impl Camera2dBundle {
|
|||||||
// the camera's translation by far and use a right handed coordinate system
|
// the camera's translation by far and use a right handed coordinate system
|
||||||
let projection = OrthographicProjection {
|
let projection = OrthographicProjection {
|
||||||
far,
|
far,
|
||||||
..Default::default()
|
..OrthographicProjection::default_2d()
|
||||||
};
|
};
|
||||||
let transform = Transform::from_xyz(0.0, 0.0, far - 0.1);
|
let transform = Transform::from_xyz(0.0, 0.0, far - 0.1);
|
||||||
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
|
let frustum = projection.compute_frustum(&GlobalTransform::from(transform));
|
||||||
|
|||||||
@ -92,7 +92,7 @@ fn update_debug_camera(
|
|||||||
projection: OrthographicProjection {
|
projection: OrthographicProjection {
|
||||||
far: 1000.0,
|
far: 1000.0,
|
||||||
viewport_origin: Vec2::new(0.0, 0.0),
|
viewport_origin: Vec2::new(0.0, 0.0),
|
||||||
..default()
|
..OrthographicProjection::default_3d()
|
||||||
},
|
},
|
||||||
camera: Camera {
|
camera: Camera {
|
||||||
order: LAYOUT_DEBUG_CAMERA_ORDER,
|
order: LAYOUT_DEBUG_CAMERA_ORDER,
|
||||||
|
|||||||
@ -1256,7 +1256,7 @@ fn load_node(
|
|||||||
far: orthographic.zfar(),
|
far: orthographic.zfar(),
|
||||||
scaling_mode: ScalingMode::FixedHorizontal(1.0),
|
scaling_mode: ScalingMode::FixedHorizontal(1.0),
|
||||||
scale: xmag,
|
scale: xmag,
|
||||||
..Default::default()
|
..OrthographicProjection::default_3d()
|
||||||
};
|
};
|
||||||
|
|
||||||
Projection::Orthographic(orthographic_projection)
|
Projection::Orthographic(orthographic_projection)
|
||||||
|
|||||||
@ -237,7 +237,7 @@ impl Default for PerspectiveProjection {
|
|||||||
/// # use bevy_render::camera::{OrthographicProjection, Projection, ScalingMode};
|
/// # use bevy_render::camera::{OrthographicProjection, Projection, ScalingMode};
|
||||||
/// let projection = Projection::Orthographic(OrthographicProjection {
|
/// let projection = Projection::Orthographic(OrthographicProjection {
|
||||||
/// scaling_mode: ScalingMode::FixedVertical(2.0),
|
/// scaling_mode: ScalingMode::FixedVertical(2.0),
|
||||||
/// ..OrthographicProjection::default()
|
/// ..OrthographicProjection::default_2d()
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize)]
|
||||||
@ -334,11 +334,11 @@ impl DivAssign<f32> for ScalingMode {
|
|||||||
/// # use bevy_render::camera::{OrthographicProjection, Projection, ScalingMode};
|
/// # use bevy_render::camera::{OrthographicProjection, Projection, ScalingMode};
|
||||||
/// let projection = Projection::Orthographic(OrthographicProjection {
|
/// let projection = Projection::Orthographic(OrthographicProjection {
|
||||||
/// scaling_mode: ScalingMode::WindowSize(100.0),
|
/// scaling_mode: ScalingMode::WindowSize(100.0),
|
||||||
/// ..OrthographicProjection::default()
|
/// ..OrthographicProjection::default_2d()
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Component, Debug, Clone, Reflect)]
|
#[derive(Component, Debug, Clone, Reflect)]
|
||||||
#[reflect(Component, Default)]
|
#[reflect(Component)]
|
||||||
pub struct OrthographicProjection {
|
pub struct OrthographicProjection {
|
||||||
/// The distance of the near clipping plane in world units.
|
/// The distance of the near clipping plane in world units.
|
||||||
///
|
///
|
||||||
@ -479,8 +479,29 @@ impl CameraProjection for OrthographicProjection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for OrthographicProjection {
|
impl FromWorld for OrthographicProjection {
|
||||||
fn default() -> Self {
|
fn from_world(_world: &mut World) -> Self {
|
||||||
|
OrthographicProjection::default_3d()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrthographicProjection {
|
||||||
|
/// Returns the default orthographic projection for a 2D context.
|
||||||
|
///
|
||||||
|
/// The near plane is set to a negative value so that the camera can still
|
||||||
|
/// render the scene when using positive z coordinates to order foreground elements.
|
||||||
|
pub fn default_2d() -> Self {
|
||||||
|
OrthographicProjection {
|
||||||
|
near: -1000.0,
|
||||||
|
..OrthographicProjection::default_3d()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the default orthographic projection for a 3D context.
|
||||||
|
///
|
||||||
|
/// The near plane is set to 0.0 so that the camera doesn't render
|
||||||
|
/// objects that are behind it.
|
||||||
|
pub fn default_3d() -> Self {
|
||||||
OrthographicProjection {
|
OrthographicProjection {
|
||||||
scale: 1.0,
|
scale: 1.0,
|
||||||
near: 0.0,
|
near: 0.0,
|
||||||
|
|||||||
@ -20,7 +20,7 @@ fn setup(
|
|||||||
projection: OrthographicProjection {
|
projection: OrthographicProjection {
|
||||||
// 6 world units per window height.
|
// 6 world units per window height.
|
||||||
scaling_mode: ScalingMode::FixedVertical(6.0),
|
scaling_mode: ScalingMode::FixedVertical(6.0),
|
||||||
..default()
|
..OrthographicProjection::default_3d()
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
transform: Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
|
transform: Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||||
|
|||||||
@ -121,7 +121,7 @@ fn setup(
|
|||||||
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::default(), Vec3::Y),
|
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::default(), Vec3::Y),
|
||||||
projection: OrthographicProjection {
|
projection: OrthographicProjection {
|
||||||
scale: 0.01,
|
scale: 0.01,
|
||||||
..default()
|
..OrthographicProjection::default_3d()
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
..default()
|
..default()
|
||||||
|
|||||||
@ -96,7 +96,7 @@ fn setup(
|
|||||||
projection: OrthographicProjection {
|
projection: OrthographicProjection {
|
||||||
scale: 20.0,
|
scale: 20.0,
|
||||||
scaling_mode: ScalingMode::FixedHorizontal(1.0),
|
scaling_mode: ScalingMode::FixedHorizontal(1.0),
|
||||||
..default()
|
..OrthographicProjection::default_3d()
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
..default()
|
..default()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user