From dd3386740fb464a517d2bfc5303b0605f65f9f06 Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Wed, 5 Oct 2022 17:33:42 -0600 Subject: [PATCH 01/19] Document `OrthographicProjection` --- crates/bevy_render/src/camera/projection.rs | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 27cb37851128f..874572bb13001 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -199,17 +199,49 @@ pub enum ScalingMode { FixedHorizontal(f32), } +/// Project a 3D space onto a 2D surface using parallel lines, i.e., objects have the same +/// apparent size regardless of depth. The volume contained in the projection is called the view frustum. +/// +/// If the window is smaller than the view frustum, some objects within the view frustum will not appear on the screen. +/// +/// Note that the cross sectional area of the view frustum and the apparent size of objects are inversely proportional. #[derive(Component, Debug, Clone, Reflect, FromReflect)] #[reflect(Component, Default)] pub struct OrthographicProjection { + /// The location of the left face of the camera's view frustum relative to the `window_origin`, measured in + /// world units. + /// + /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub left: f32, + /// The location of the right face of the camera's view frustum relative to the `window_origin`, measured in + /// world units. + /// + /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub right: f32, + /// The location of the bottom face of the camera's view frustum relative to the `window_origin`, measured in + /// world units. + /// + /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub bottom: f32, + /// The location of the top face of the camera's view frustum relative to the `window_origin`, measured in + /// world units. + /// + /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub top: f32, + /// The distance of the near clipping plane, in world units. + /// + /// Objects closer than this will not be rendered. pub near: f32, + /// The distance of the far clipping plane, in world units. + /// + /// Objects further than this will not be rendered. pub far: f32, + /// Specifies where `(0, 0)` is located. pub window_origin: WindowOrigin, pub scaling_mode: ScalingMode, + /// Scales the cross sectional area of the view frustum. + /// + /// As `scale` increases, the apparent size of objects decrease, and vise versa. pub scale: f32, } From cea21fbe58e695a511c1d000113633250db8f8bf Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Thu, 6 Oct 2022 16:24:44 -0600 Subject: [PATCH 02/19] Improve docs for `OrthographicProjection` --- crates/bevy_render/src/camera/projection.rs | 39 ++++++++++++--------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 874572bb13001..a8e2f6176d567 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -173,7 +173,15 @@ impl Default for PerspectiveProjection { #[derive(Debug, Clone, Reflect, FromReflect, Serialize, Deserialize)] #[reflect(Serialize, Deserialize)] pub enum WindowOrigin { + /// Scale the view frustum from the center. + /// + /// When resizing the window, object in the center of the screen remain in the center, while opposite + /// faces of the view frustum expand/shrink equally. Center, + /// Scale the view frustum from the bottom left corner. + /// + /// When resizing the window, the top and right faces of the view frustum will move accordingly, keeping + /// the bottom and left faces in place. BottomLeft, } @@ -199,49 +207,48 @@ pub enum ScalingMode { FixedHorizontal(f32), } -/// Project a 3D space onto a 2D surface using parallel lines, i.e., objects have the same -/// apparent size regardless of depth. The volume contained in the projection is called the view frustum. +/// Project a 3D space onto a 2D surface using parallel lines, i.e., unlike [`PerspectiveProjection`], +/// the size at which objects appear remain the same regardless of depth. /// -/// If the window is smaller than the view frustum, some objects within the view frustum will not appear on the screen. +/// The volume contained in the projection is called the *view frustum*. Since the viewport is rectangular, +/// the view frustum is in the shape of a rectangular prism. /// /// Note that the cross sectional area of the view frustum and the apparent size of objects are inversely proportional. #[derive(Component, Debug, Clone, Reflect, FromReflect)] #[reflect(Component, Default)] pub struct OrthographicProjection { - /// The location of the left face of the camera's view frustum relative to the `window_origin`, measured in - /// world units. + /// The distance of the left face of the view frustum relative to the camera, measured in world units. /// /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub left: f32, - /// The location of the right face of the camera's view frustum relative to the `window_origin`, measured in - /// world units. + /// The distance of the right face of the view frustum relative to the camera, measured in world units. /// /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub right: f32, - /// The location of the bottom face of the camera's view frustum relative to the `window_origin`, measured in - /// world units. + /// The distance the bottom face of the view frustum relative to the camera, measured in world units. /// /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub bottom: f32, - /// The location of the top face of the camera's view frustum relative to the `window_origin`, measured in - /// world units. + /// The distance of the top face of the view frustum relative to the camera, measured in world units. /// /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. pub top: f32, - /// The distance of the near clipping plane, in world units. + /// The distance of the near clipping plane in world units. /// /// Objects closer than this will not be rendered. pub near: f32, - /// The distance of the far clipping plane, in world units. + /// The distance of the far clipping plane in world units. /// /// Objects further than this will not be rendered. pub far: f32, - /// Specifies where `(0, 0)` is located. + /// Specifies the origin of the scaling. + /// + /// This will not have any effect if `scaling_mode` is set to `ScalingMode::None`. pub window_origin: WindowOrigin, pub scaling_mode: ScalingMode, - /// Scales the cross sectional area of the view frustum. + /// Scales the width and height of the view frustum. /// - /// As `scale` increases, the apparent size of objects decrease, and vise versa. + /// As `scale` increases, the apparent size of objects decreases, and vice versa. pub scale: f32, } From 4327477dc5d68b7351792b2a9aeb14256ed0d3dd Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Sat, 8 Oct 2022 10:25:55 -0600 Subject: [PATCH 03/19] Revamp `OrthographicProjection` and add docs --- crates/bevy_render/src/camera/mod.rs | 1 - crates/bevy_render/src/camera/projection.rs | 118 +++++++------------- 2 files changed, 39 insertions(+), 80 deletions(-) diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index a3c46471955cb..cdd26a36c638a 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -18,7 +18,6 @@ impl Plugin for CameraPlugin { app.register_type::() .register_type::() .register_type::>() - .register_type::() .register_type::() .register_type::() .register_type::() diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index a8e2f6176d567..ace63ac2c12ae 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -169,41 +169,26 @@ impl Default for PerspectiveProjection { } } -// TODO: make this a component instead of a property -#[derive(Debug, Clone, Reflect, FromReflect, Serialize, Deserialize)] -#[reflect(Serialize, Deserialize)] -pub enum WindowOrigin { - /// Scale the view frustum from the center. - /// - /// When resizing the window, object in the center of the screen remain in the center, while opposite - /// faces of the view frustum expand/shrink equally. - Center, - /// Scale the view frustum from the bottom left corner. - /// - /// When resizing the window, the top and right faces of the view frustum will move accordingly, keeping - /// the bottom and left faces in place. - BottomLeft, -} - #[derive(Debug, Clone, Reflect, FromReflect, Serialize, Deserialize)] #[reflect(Serialize, Deserialize)] pub enum ScalingMode { - /// Manually specify left/right/top/bottom values. + /// Manually specify the projection's size with `width` and `height`. /// Ignore window resizing; the image will stretch. - None, - /// Match the window size. 1 world unit = 1 pixel. - WindowSize, + None { width: f32, height: f32 }, + /// Match the window size. + /// The argument is the number of pixels that equals one world unit. + WindowSize(f32), /// Keeping the aspect ratio while the axes can't be smaller than given minimum. /// Arguments are in world units. AutoMin { min_width: f32, min_height: f32 }, /// Keeping the aspect ratio while the axes can't be bigger than given maximum. /// Arguments are in world units. AutoMax { max_width: f32, max_height: f32 }, - /// Keep vertical axis constant; resize horizontal with aspect ratio. - /// The argument is the desired height of the viewport in world units. + /// Keep the projection's height constant; adjust width to match aspect ratio. + /// The argument is the desired height of the projection in world units. FixedVertical(f32), - /// Keep horizontal axis constant; resize vertical with aspect ratio. - /// The argument is the desired width of the viewport in world units. + /// Keep the projection's width constant; adjust height to match aspect ratio. + /// The argument is the desired width of the projection in world units. FixedHorizontal(f32), } @@ -217,22 +202,6 @@ pub enum ScalingMode { #[derive(Component, Debug, Clone, Reflect, FromReflect)] #[reflect(Component, Default)] pub struct OrthographicProjection { - /// The distance of the left face of the view frustum relative to the camera, measured in world units. - /// - /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. - pub left: f32, - /// The distance of the right face of the view frustum relative to the camera, measured in world units. - /// - /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. - pub right: f32, - /// The distance the bottom face of the view frustum relative to the camera, measured in world units. - /// - /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. - pub bottom: f32, - /// The distance of the top face of the view frustum relative to the camera, measured in world units. - /// - /// This value will be set automatically unless `scaling_mode` is set to [`ScalingMode::None`]. - pub top: f32, /// The distance of the near clipping plane in world units. /// /// Objects closer than this will not be rendered. @@ -241,24 +210,33 @@ pub struct OrthographicProjection { /// /// Objects further than this will not be rendered. pub far: f32, - /// Specifies the origin of the scaling. + /// Specifies the origin of the viewport as a fraction of its width and height (from the bottom left corner). + /// Consequently, this is the point from where scaling caused by viewport resizing will occur. /// - /// This will not have any effect if `scaling_mode` is set to `ScalingMode::None`. - pub window_origin: WindowOrigin, + /// For example, if `viewport_origin` is set to (0.2, 0.6) and the size of the viewport is (10, 10), + /// the location of the camera will determine where the point (2, 6) on the viewport is; + /// if the projection needs to triple in width, it will expand 4 units to the left and + /// 16 units to the right (20% and 80% of the total scaling, respectively). + pub viewport_origin: (f32, f32), + /// How the projection will scale when the viewport is resized. pub scaling_mode: ScalingMode, - /// Scales the width and height of the view frustum. + /// Scales the projection, in world units. /// - /// As `scale` increases, the apparent size of objects decreases, and vice versa. + /// As scale increases, the apparent size of objects decreases, and vice versa. pub scale: f32, + pub left: f32, + pub right: f32, + pub bottom: f32, + pub top: f32, } impl CameraProjection for OrthographicProjection { fn get_projection_matrix(&self) -> Mat4 { Mat4::orthographic_rh( - self.left * self.scale, - self.right * self.scale, - self.bottom * self.scale, - self.top * self.scale, + self.left, + self.right, + self.bottom, + self.top, // NOTE: near and far are swapped to invert the depth range from [0,1] to [1,0] // This is for interoperability with pipelines using infinite reverse perspective projections. self.far, @@ -267,8 +245,8 @@ impl CameraProjection for OrthographicProjection { } fn update(&mut self, width: f32, height: f32) { - let (viewport_width, viewport_height) = match self.scaling_mode { - ScalingMode::WindowSize => (width, height), + let (frustum_width, frustum_height) = match self.scaling_mode { + ScalingMode::WindowSize(pixel_scale) => (width / pixel_scale, height / pixel_scale), ScalingMode::AutoMin { min_width, min_height, @@ -299,34 +277,16 @@ impl CameraProjection for OrthographicProjection { ScalingMode::FixedHorizontal(viewport_width) => { (viewport_width, height * viewport_width / width) } - ScalingMode::None => return, + ScalingMode::None { width, height } => (width, height), }; - match self.window_origin { - WindowOrigin::Center => { - let half_width = viewport_width / 2.0; - let half_height = viewport_height / 2.0; - self.left = -half_width; - self.bottom = -half_height; - self.right = half_width; - self.top = half_height; + let origin_x = frustum_width * self.viewport_origin.0; + let origin_y = frustum_height * self.viewport_origin.1; - if let ScalingMode::WindowSize = self.scaling_mode { - if self.scale == 1.0 { - self.left = self.left.floor(); - self.bottom = self.bottom.floor(); - self.right = self.right.floor(); - self.top = self.top.floor(); - } - } - } - WindowOrigin::BottomLeft => { - self.left = 0.0; - self.bottom = 0.0; - self.right = viewport_width; - self.top = viewport_height; - } - } + self.left = -origin_x * self.scale; + self.bottom = -origin_y * self.scale; + self.right = (frustum_width - origin_x) * self.scale; + self.top = (frustum_height - origin_y) * self.scale; } fn far(&self) -> f32 { @@ -341,11 +301,11 @@ impl Default for OrthographicProjection { right: 1.0, bottom: -1.0, top: 1.0, + scale: 1.0, near: 0.0, far: 1000.0, - window_origin: WindowOrigin::Center, - scaling_mode: ScalingMode::WindowSize, - scale: 1.0, + viewport_origin: (0.5, 0.5), + scaling_mode: ScalingMode::WindowSize(10.0), } } } From a6b3bf4ed5f4334615db5005296bbf9174f82e08 Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Sun, 9 Oct 2022 18:42:00 -0600 Subject: [PATCH 04/19] Fix docs tenses Co-authored-by: sark --- crates/bevy_render/src/camera/projection.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index ace63ac2c12ae..655cab504f531 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -184,10 +184,10 @@ pub enum ScalingMode { /// Keeping the aspect ratio while the axes can't be bigger than given maximum. /// Arguments are in world units. AutoMax { max_width: f32, max_height: f32 }, - /// Keep the projection's height constant; adjust width to match aspect ratio. + /// Keep the projection's height constant; width will be adjusted to match aspect ratio. /// The argument is the desired height of the projection in world units. FixedVertical(f32), - /// Keep the projection's width constant; adjust height to match aspect ratio. + /// Keep the projection's width constant; height will be adjusted to match aspect ratio. /// The argument is the desired width of the projection in world units. FixedHorizontal(f32), } From fa9c7684a7ee709057a84aff3c82b56483617758 Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Mon, 10 Oct 2022 11:26:56 -0600 Subject: [PATCH 05/19] Rename `ScalingMode::None` and improve docs --- crates/bevy_render/src/camera/projection.rs | 35 +++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 655cab504f531..d7ee7aacacb2a 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -172,9 +172,10 @@ impl Default for PerspectiveProjection { #[derive(Debug, Clone, Reflect, FromReflect, Serialize, Deserialize)] #[reflect(Serialize, Deserialize)] pub enum ScalingMode { - /// Manually specify the projection's size with `width` and `height`. + /// Manually specify the projection's size. + /// /// Ignore window resizing; the image will stretch. - None { width: f32, height: f32 }, + Fixed { width: f32, height: f32 }, /// Match the window size. /// The argument is the number of pixels that equals one world unit. WindowSize(f32), @@ -195,10 +196,11 @@ pub enum ScalingMode { /// Project a 3D space onto a 2D surface using parallel lines, i.e., unlike [`PerspectiveProjection`], /// the size at which objects appear remain the same regardless of depth. /// -/// The volume contained in the projection is called the *view frustum*. Since the viewport is rectangular, -/// the view frustum is in the shape of a rectangular prism. +/// The volume contained in the projection is called the *view frustum*. Since the viewport is rectangular +/// and projection lines are parallel, the view frustum takes the shape of a rectangular prism. /// -/// Note that the cross sectional area of the view frustum and the apparent size of objects are inversely proportional. +/// Note that the scale of the projection and the apparent size of objects are inversely proportional. +/// As the size of the projection increases, the apparent size of objects decreases. #[derive(Component, Debug, Clone, Reflect, FromReflect)] #[reflect(Component, Default)] pub struct OrthographicProjection { @@ -210,13 +212,20 @@ pub struct OrthographicProjection { /// /// Objects further than this will not be rendered. pub far: f32, - /// Specifies the origin of the viewport as a fraction of its width and height (from the bottom left corner). - /// Consequently, this is the point from where scaling caused by viewport resizing will occur. + /// Specifies the origin of the viewport as a normalized position from 0 to 1, where (0, 0) is the bottom left + /// and (1, 1) is the top right. This determines where the position of the camera sits inside the viewport. + /// + /// This is also the pivot point when resizing the viewport. With a bottom left pivot, the projection will expand + /// upwards and to the right. With a top right pivot, the projection will expand downwards and to the left. + /// Values in between will caused the projection to scale proportionally on each axis. + /// + /// If `scaling_mode` is set to anything other than `ScalingMode::None`, resizing the viewport will also scale the + /// projection. When the projection scales, the position of the camera doesn't change, and since `viewport_origin` + /// specifies the point on the viewport where the camera sits, this point will always remain at the same position + /// (relative to the viewport size; if `viewport_origin` is (0.3, 0.6), objects at (0.3, 0.6) (normalized) on the + /// viewport will always remain at (0.3, 0.6) (normalized). /// - /// For example, if `viewport_origin` is set to (0.2, 0.6) and the size of the viewport is (10, 10), - /// the location of the camera will determine where the point (2, 6) on the viewport is; - /// if the projection needs to triple in width, it will expand 4 units to the left and - /// 16 units to the right (20% and 80% of the total scaling, respectively). + /// Set this to (0.5, 0.5) make scaling affect opposite sides equally, thereby keeping centered objects on each axis centered. pub viewport_origin: (f32, f32), /// How the projection will scale when the viewport is resized. pub scaling_mode: ScalingMode, @@ -277,7 +286,7 @@ impl CameraProjection for OrthographicProjection { ScalingMode::FixedHorizontal(viewport_width) => { (viewport_width, height * viewport_width / width) } - ScalingMode::None { width, height } => (width, height), + ScalingMode::Fixed { width, height } => (width, height), }; let origin_x = frustum_width * self.viewport_origin.0; @@ -305,7 +314,7 @@ impl Default for OrthographicProjection { near: 0.0, far: 1000.0, viewport_origin: (0.5, 0.5), - scaling_mode: ScalingMode::WindowSize(10.0), + scaling_mode: ScalingMode::WindowSize(1.0), } } } From 2c330072058f36d0f216db4531f917a369598cdd Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Tue, 11 Oct 2022 13:18:06 -0600 Subject: [PATCH 06/19] Make `OrthographicProjection` size fields private and add constructor --- .../src/core_2d/camera_2d.rs | 5 +- crates/bevy_gltf/src/loader.rs | 11 +-- crates/bevy_render/src/camera/projection.rs | 89 ++++++++++++++++++- examples/3d/orthographic.rs | 10 +-- examples/3d/pbr.rs | 6 +- examples/stress_tests/many_lights.rs | 10 +-- examples/tools/scene_viewer.rs | 0 7 files changed, 99 insertions(+), 32 deletions(-) create mode 100644 examples/tools/scene_viewer.rs diff --git a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs index 0eb793228b9fa..f95e0599a31ca 100644 --- a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs +++ b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs @@ -45,10 +45,7 @@ impl Camera2dBundle { pub fn new_with_far(far: f32) -> Self { // we want 0 to be "closest" and +far to be "farthest" in 2d, so we offset // the camera's translation by far and use a right handed coordinate system - let projection = OrthographicProjection { - far, - ..Default::default() - }; + let projection = OrthographicProjection::new().clipping_plane(0.0, far); let transform = Transform::from_xyz(0.0, 0.0, far - 0.1); let view_projection = projection.get_projection_matrix() * transform.compute_matrix().inverse(); diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 81d793993ac7c..84f62cf7a4efb 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -719,13 +719,10 @@ fn load_node( let projection = match camera.projection() { gltf::camera::Projection::Orthographic(orthographic) => { let xmag = orthographic.xmag(); - let orthographic_projection: OrthographicProjection = OrthographicProjection { - far: orthographic.zfar(), - near: orthographic.znear(), - scaling_mode: ScalingMode::FixedHorizontal(1.0), - scale: xmag, - ..Default::default() - }; + let orthographic_projection = OrthographicProjection::new() + .clipping_plane(orthographic.znear(), orthographic.zfar()) + .scaling_mode(ScalingMode::FixedHorizontal(1.0)) + .scale(xmag); Projection::Orthographic(orthographic_projection) } diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index d7ee7aacacb2a..9961d327c2752 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -233,10 +233,10 @@ pub struct OrthographicProjection { /// /// As scale increases, the apparent size of objects decreases, and vice versa. pub scale: f32, - pub left: f32, - pub right: f32, - pub bottom: f32, - pub top: f32, + left: f32, + right: f32, + bottom: f32, + top: f32, } impl CameraProjection for OrthographicProjection { @@ -318,3 +318,84 @@ impl Default for OrthographicProjection { } } } + +impl OrthographicProjection { + /// Create a new `OrthographicProjection` with default values. + /// + /// Use its other methods to modify its properties, or modify them after creation if `mut`. + /// + /// ``` + /// use bevy_render::camera::{OrthographicProjection, ScalingMode}; + /// let projection = OrthographicProjection::new() + /// .scale(1.0) + /// .clipping_plane(0.0, 1000.0) + /// .viewport_origin(0.5, 0.5) + /// .scaling_mode(ScalingMode::WindowSize(1.0)); + /// ``` + pub fn new() -> Self { + OrthographicProjection { + left: 0.0, + right: 0.0, + bottom: 0.0, + top: 0.0, + scale: 1.0, + near: 0.0, + far: 1000.0, + viewport_origin: (0.5, 0.5), + scaling_mode: ScalingMode::WindowSize(1.0), + } + } + + /// Set the scale of the projection. + pub fn scale(mut self, scale: f32) -> Self { + self.scale = scale; + self + } + + /// Set the near and far clipping planes of the projection. + pub fn clipping_plane(mut self, near: f32, far: f32) -> Self { + self.near = near; + self.far = far; + self + } + + /// Set the viewport origin of the projection. + pub fn viewport_origin(mut self, x: f32, y: f32) -> Self { + self.viewport_origin = (x, y); + self + } + + /// Set the scaling mode of the projection. + pub fn scaling_mode(mut self, scaling_mode: ScalingMode) -> Self { + self.scaling_mode = scaling_mode; + self + } + + /// Get the distance of the left side of the projection in world units. + /// + /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. + pub fn left(&self) -> f32 { + self.left + } + + /// Get the distance of the right side of the projection in world units. + /// + /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. + pub fn right(&self) -> f32 { + self.right + } + + /// Get the distance of the right side of the projection in world units. + /// + /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. + pub fn bottom(&self) -> f32 { + self.bottom + } + + /// Get the distance of the right side of the projection in world units. + /// + /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. + pub fn top(&self) -> f32 { + self.top + } +} diff --git a/examples/3d/orthographic.rs b/examples/3d/orthographic.rs index 920706674cdb3..0dd9b140da7ee 100644 --- a/examples/3d/orthographic.rs +++ b/examples/3d/orthographic.rs @@ -17,12 +17,10 @@ fn setup( ) { // camera commands.spawn(Camera3dBundle { - projection: OrthographicProjection { - scale: 3.0, - scaling_mode: ScalingMode::FixedVertical(2.0), - ..default() - } - .into(), + projection: OrthographicProjection::new() + .scale(3.0) + .scaling_mode(ScalingMode::FixedVertical(2.0)) + .into(), transform: Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() }); diff --git a/examples/3d/pbr.rs b/examples/3d/pbr.rs index c3159cff3fcea..2af35c81d5b6e 100644 --- a/examples/3d/pbr.rs +++ b/examples/3d/pbr.rs @@ -72,11 +72,7 @@ fn setup( // camera commands.spawn(Camera3dBundle { transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::default(), Vec3::Y), - projection: OrthographicProjection { - scale: 0.01, - ..default() - } - .into(), + projection: OrthographicProjection::new().scale(0.01).into(), ..default() }); } diff --git a/examples/stress_tests/many_lights.rs b/examples/stress_tests/many_lights.rs index b722100e7cfe4..1ee46aa351c0e 100644 --- a/examples/stress_tests/many_lights.rs +++ b/examples/stress_tests/many_lights.rs @@ -87,12 +87,10 @@ fn setup( // camera match std::env::args().nth(1).as_deref() { Some("orthographic") => commands.spawn(Camera3dBundle { - projection: OrthographicProjection { - scale: 20.0, - scaling_mode: ScalingMode::FixedHorizontal(1.0), - ..default() - } - .into(), + projection: OrthographicProjection::new() + .scale(20.0) + .scaling_mode(ScalingMode::FixedHorizontal(1.0)) + .into(), ..default() }), _ => commands.spawn(Camera3dBundle::default()), diff --git a/examples/tools/scene_viewer.rs b/examples/tools/scene_viewer.rs new file mode 100644 index 0000000000000..e69de29bb2d1d From d7189320a6d6c5d00f161d96e9d7f9c134ca7607 Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Wed, 12 Oct 2022 11:36:27 -0600 Subject: [PATCH 07/19] Fix `ScalingMode` docs --- crates/bevy_render/src/camera/projection.rs | 22 +++++++++------------ 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 9961d327c2752..95c0c4fc3b948 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -172,11 +172,10 @@ impl Default for PerspectiveProjection { #[derive(Debug, Clone, Reflect, FromReflect, Serialize, Deserialize)] #[reflect(Serialize, Deserialize)] pub enum ScalingMode { - /// Manually specify the projection's size. - /// - /// Ignore window resizing; the image will stretch. + /// Manually specify the projection's size, ignoring window resizing; the image will stretch. + /// Arguments are in world units Fixed { width: f32, height: f32 }, - /// Match the window size. + /// Match the viewport size. /// The argument is the number of pixels that equals one world unit. WindowSize(f32), /// Keeping the aspect ratio while the axes can't be smaller than given minimum. @@ -214,18 +213,15 @@ pub struct OrthographicProjection { pub far: f32, /// Specifies the origin of the viewport as a normalized position from 0 to 1, where (0, 0) is the bottom left /// and (1, 1) is the top right. This determines where the position of the camera sits inside the viewport. + /// Set this to (0.5, 0.5) make scaling affect opposite sides equally, thereby keeping centered objects on each axis centered. + /// + /// When the projection scales due to viewport resizing (assuming `scaling_mode` is not set to `Fixed`), the position + /// of the camera doesn't change, and since `viewport_origin` specifies the point on the viewport where the camera sits, + /// this point will always remain at the same position (relatively on the viewport). /// - /// This is also the pivot point when resizing the viewport. With a bottom left pivot, the projection will expand + /// Consequently, this is pivot point when scaling. With a bottom left pivot, the projection will expand /// upwards and to the right. With a top right pivot, the projection will expand downwards and to the left. /// Values in between will caused the projection to scale proportionally on each axis. - /// - /// If `scaling_mode` is set to anything other than `ScalingMode::None`, resizing the viewport will also scale the - /// projection. When the projection scales, the position of the camera doesn't change, and since `viewport_origin` - /// specifies the point on the viewport where the camera sits, this point will always remain at the same position - /// (relative to the viewport size; if `viewport_origin` is (0.3, 0.6), objects at (0.3, 0.6) (normalized) on the - /// viewport will always remain at (0.3, 0.6) (normalized). - /// - /// Set this to (0.5, 0.5) make scaling affect opposite sides equally, thereby keeping centered objects on each axis centered. pub viewport_origin: (f32, f32), /// How the projection will scale when the viewport is resized. pub scaling_mode: ScalingMode, From 2987db1e6ab8981ff9c6b383137f0fca2a14314f Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Sat, 15 Oct 2022 20:46:35 -0600 Subject: [PATCH 08/19] Minor docs fixes --- crates/bevy_render/src/camera/projection.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 95c0c4fc3b948..e4f6cc4f52856 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -172,7 +172,7 @@ impl Default for PerspectiveProjection { #[derive(Debug, Clone, Reflect, FromReflect, Serialize, Deserialize)] #[reflect(Serialize, Deserialize)] pub enum ScalingMode { - /// Manually specify the projection's size, ignoring window resizing; the image will stretch. + /// Manually specify the projection's size, ignoring window resizing. The image will stretch. /// Arguments are in world units Fixed { width: f32, height: f32 }, /// Match the viewport size. @@ -212,12 +212,12 @@ pub struct OrthographicProjection { /// Objects further than this will not be rendered. pub far: f32, /// Specifies the origin of the viewport as a normalized position from 0 to 1, where (0, 0) is the bottom left - /// and (1, 1) is the top right. This determines where the position of the camera sits inside the viewport. - /// Set this to (0.5, 0.5) make scaling affect opposite sides equally, thereby keeping centered objects on each axis centered. + /// and (1, 1) is the top right. This determines where the camera's position sits inside the viewport. + /// Set this to (0.5, 0.5) to make scaling affect opposite sides equally, thereby keeping centered objects on each axis centered. /// /// When the projection scales due to viewport resizing (assuming `scaling_mode` is not set to `Fixed`), the position /// of the camera doesn't change, and since `viewport_origin` specifies the point on the viewport where the camera sits, - /// this point will always remain at the same position (relatively on the viewport). + /// this point will always remain at the same position (relative on the viewport). /// /// Consequently, this is pivot point when scaling. With a bottom left pivot, the projection will expand /// upwards and to the right. With a top right pivot, the projection will expand downwards and to the left. @@ -250,7 +250,7 @@ impl CameraProjection for OrthographicProjection { } fn update(&mut self, width: f32, height: f32) { - let (frustum_width, frustum_height) = match self.scaling_mode { + let (projection_width, projection_height) = match self.scaling_mode { ScalingMode::WindowSize(pixel_scale) => (width / pixel_scale, height / pixel_scale), ScalingMode::AutoMin { min_width, @@ -285,13 +285,13 @@ impl CameraProjection for OrthographicProjection { ScalingMode::Fixed { width, height } => (width, height), }; - let origin_x = frustum_width * self.viewport_origin.0; - let origin_y = frustum_height * self.viewport_origin.1; + let origin_x = projection_width * self.viewport_origin.0; + let origin_y = projection_height * self.viewport_origin.1; self.left = -origin_x * self.scale; self.bottom = -origin_y * self.scale; - self.right = (frustum_width - origin_x) * self.scale; - self.top = (frustum_height - origin_y) * self.scale; + self.right = (projection_width - origin_x) * self.scale; + self.top = (projection_height - origin_y) * self.scale; } fn far(&self) -> f32 { @@ -318,7 +318,7 @@ impl Default for OrthographicProjection { impl OrthographicProjection { /// Create a new `OrthographicProjection` with default values. /// - /// Use its other methods to modify its properties, or modify them after creation if `mut`. + /// Use its other methods to modify its properties, or modify them after creation. /// /// ``` /// use bevy_render::camera::{OrthographicProjection, ScalingMode}; From d5317a814d51c2a453fa5439f2a0dab0d888f901 Mon Sep 17 00:00:00 2001 From: xgbwei Date: Mon, 7 Nov 2022 23:07:22 -0700 Subject: [PATCH 09/19] Fix minor docs issues Co-authored-by: Jerome Humbert --- crates/bevy_render/src/camera/projection.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index e4f6cc4f52856..61550b3695db6 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -173,7 +173,7 @@ impl Default for PerspectiveProjection { #[reflect(Serialize, Deserialize)] pub enum ScalingMode { /// Manually specify the projection's size, ignoring window resizing. The image will stretch. - /// Arguments are in world units + /// Arguments are in world units. Fixed { width: f32, height: f32 }, /// Match the viewport size. /// The argument is the number of pixels that equals one world unit. @@ -193,7 +193,7 @@ pub enum ScalingMode { } /// Project a 3D space onto a 2D surface using parallel lines, i.e., unlike [`PerspectiveProjection`], -/// the size at which objects appear remain the same regardless of depth. +/// the size of objects remain the same regardless of their distance to camera. /// /// The volume contained in the projection is called the *view frustum*. Since the viewport is rectangular /// and projection lines are parallel, the view frustum takes the shape of a rectangular prism. From 4924ed067b72113fdc66e0d44e982efda55d134d Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Thu, 17 Nov 2022 12:41:57 -0700 Subject: [PATCH 10/19] Remove `OrthographicProjection` constructor and add docs --- .../src/core_2d/camera_2d.rs | 5 +- crates/bevy_gltf/src/loader.rs | 12 +- crates/bevy_render/src/camera/projection.rs | 103 +++--------------- examples/3d/orthographic.rs | 10 +- examples/3d/pbr.rs | 6 +- examples/stress_tests/many_lights.rs | 10 +- 6 files changed, 46 insertions(+), 100 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs index f95e0599a31ca..0eb793228b9fa 100644 --- a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs +++ b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs @@ -45,7 +45,10 @@ impl Camera2dBundle { pub fn new_with_far(far: f32) -> Self { // we want 0 to be "closest" and +far to be "farthest" in 2d, so we offset // the camera's translation by far and use a right handed coordinate system - let projection = OrthographicProjection::new().clipping_plane(0.0, far); + let projection = OrthographicProjection { + far, + ..Default::default() + }; let transform = Transform::from_xyz(0.0, 0.0, far - 0.1); let view_projection = projection.get_projection_matrix() * transform.compute_matrix().inverse(); diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 84f62cf7a4efb..a148f0476772c 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -719,10 +719,14 @@ fn load_node( let projection = match camera.projection() { gltf::camera::Projection::Orthographic(orthographic) => { let xmag = orthographic.xmag(); - let orthographic_projection = OrthographicProjection::new() - .clipping_plane(orthographic.znear(), orthographic.zfar()) - .scaling_mode(ScalingMode::FixedHorizontal(1.0)) - .scale(xmag); + + let orthographic_projection = OrthographicProjection { + near: orthographic.znear(), + far: orthographic.zfar(), + scaling_mode: ScalingMode::FixedHorizontal(1.0), + scale: xmag, + ..Default::default() + }; Projection::Orthographic(orthographic_projection) } diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 61550b3695db6..d8ab3d2881b65 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -225,14 +225,26 @@ pub struct OrthographicProjection { pub viewport_origin: (f32, f32), /// How the projection will scale when the viewport is resized. pub scaling_mode: ScalingMode, - /// Scales the projection, in world units. + /// Scales the projection in world units. /// /// As scale increases, the apparent size of objects decreases, and vice versa. pub scale: f32, - left: f32, - right: f32, - bottom: f32, - top: f32, + /// The distance of the left side of the projection from `viewport_origin` in world units. + /// + /// This value is automatically updated and shouldn't be manually modified. + pub left: f32, + /// The distance of the right side of the projection from `viewport_origin` in world units. + /// + /// This value is automatically updated and shouldn't be manually modified. + pub right: f32, + /// The distance of the bottom side of the projection from `viewport_origin` in world units. + /// + /// This value is automatically updated and shouldn't be manually modified. + pub bottom: f32, + /// The distance of the top side of the projection from `viewport_origin` in world units. + /// + /// This value is automatically updated and shouldn't be manually modified. + pub top: f32, } impl CameraProjection for OrthographicProjection { @@ -314,84 +326,3 @@ impl Default for OrthographicProjection { } } } - -impl OrthographicProjection { - /// Create a new `OrthographicProjection` with default values. - /// - /// Use its other methods to modify its properties, or modify them after creation. - /// - /// ``` - /// use bevy_render::camera::{OrthographicProjection, ScalingMode}; - /// let projection = OrthographicProjection::new() - /// .scale(1.0) - /// .clipping_plane(0.0, 1000.0) - /// .viewport_origin(0.5, 0.5) - /// .scaling_mode(ScalingMode::WindowSize(1.0)); - /// ``` - pub fn new() -> Self { - OrthographicProjection { - left: 0.0, - right: 0.0, - bottom: 0.0, - top: 0.0, - scale: 1.0, - near: 0.0, - far: 1000.0, - viewport_origin: (0.5, 0.5), - scaling_mode: ScalingMode::WindowSize(1.0), - } - } - - /// Set the scale of the projection. - pub fn scale(mut self, scale: f32) -> Self { - self.scale = scale; - self - } - - /// Set the near and far clipping planes of the projection. - pub fn clipping_plane(mut self, near: f32, far: f32) -> Self { - self.near = near; - self.far = far; - self - } - - /// Set the viewport origin of the projection. - pub fn viewport_origin(mut self, x: f32, y: f32) -> Self { - self.viewport_origin = (x, y); - self - } - - /// Set the scaling mode of the projection. - pub fn scaling_mode(mut self, scaling_mode: ScalingMode) -> Self { - self.scaling_mode = scaling_mode; - self - } - - /// Get the distance of the left side of the projection in world units. - /// - /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. - pub fn left(&self) -> f32 { - self.left - } - - /// Get the distance of the right side of the projection in world units. - /// - /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. - pub fn right(&self) -> f32 { - self.right - } - - /// Get the distance of the right side of the projection in world units. - /// - /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. - pub fn bottom(&self) -> f32 { - self.bottom - } - - /// Get the distance of the right side of the projection in world units. - /// - /// This value is updated automatically. Use `OrthographicProjection`'s other properties to modify its behavior. - pub fn top(&self) -> f32 { - self.top - } -} diff --git a/examples/3d/orthographic.rs b/examples/3d/orthographic.rs index 0dd9b140da7ee..920706674cdb3 100644 --- a/examples/3d/orthographic.rs +++ b/examples/3d/orthographic.rs @@ -17,10 +17,12 @@ fn setup( ) { // camera commands.spawn(Camera3dBundle { - projection: OrthographicProjection::new() - .scale(3.0) - .scaling_mode(ScalingMode::FixedVertical(2.0)) - .into(), + projection: OrthographicProjection { + scale: 3.0, + scaling_mode: ScalingMode::FixedVertical(2.0), + ..default() + } + .into(), transform: Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() }); diff --git a/examples/3d/pbr.rs b/examples/3d/pbr.rs index 2af35c81d5b6e..c3159cff3fcea 100644 --- a/examples/3d/pbr.rs +++ b/examples/3d/pbr.rs @@ -72,7 +72,11 @@ fn setup( // camera commands.spawn(Camera3dBundle { transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::default(), Vec3::Y), - projection: OrthographicProjection::new().scale(0.01).into(), + projection: OrthographicProjection { + scale: 0.01, + ..default() + } + .into(), ..default() }); } diff --git a/examples/stress_tests/many_lights.rs b/examples/stress_tests/many_lights.rs index 1ee46aa351c0e..b722100e7cfe4 100644 --- a/examples/stress_tests/many_lights.rs +++ b/examples/stress_tests/many_lights.rs @@ -87,10 +87,12 @@ fn setup( // camera match std::env::args().nth(1).as_deref() { Some("orthographic") => commands.spawn(Camera3dBundle { - projection: OrthographicProjection::new() - .scale(20.0) - .scaling_mode(ScalingMode::FixedHorizontal(1.0)) - .into(), + projection: OrthographicProjection { + scale: 20.0, + scaling_mode: ScalingMode::FixedHorizontal(1.0), + ..default() + } + .into(), ..default() }), _ => commands.spawn(Camera3dBundle::default()), From 36796dc4a97d46ba6152f7d3b24527e7e3a8b232 Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Thu, 17 Nov 2022 20:20:18 -0700 Subject: [PATCH 11/19] Replace side values with `Rect` and viewport_origin with `Vec2` --- crates/bevy_gltf/src/loader.rs | 1 - crates/bevy_render/src/camera/projection.rs | 49 ++++++++------------- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index a148f0476772c..73dd95d27606d 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -719,7 +719,6 @@ fn load_node( let projection = match camera.projection() { gltf::camera::Projection::Orthographic(orthographic) => { let xmag = orthographic.xmag(); - let orthographic_projection = OrthographicProjection { near: orthographic.znear(), far: orthographic.zfar(), diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index d8ab3d2881b65..576401d4d9d8c 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use bevy_app::{App, CoreSchedule, CoreSet, Plugin, StartupSet}; use bevy_ecs::{prelude::*, reflect::ReflectComponent}; -use bevy_math::Mat4; +use bevy_math::{Mat4, Rect, Vec2}; use bevy_reflect::{ std_traits::ReflectDefault, FromReflect, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize, @@ -222,38 +222,26 @@ pub struct OrthographicProjection { /// Consequently, this is pivot point when scaling. With a bottom left pivot, the projection will expand /// upwards and to the right. With a top right pivot, the projection will expand downwards and to the left. /// Values in between will caused the projection to scale proportionally on each axis. - pub viewport_origin: (f32, f32), + pub viewport_origin: Vec2, /// How the projection will scale when the viewport is resized. pub scaling_mode: ScalingMode, /// Scales the projection in world units. /// /// As scale increases, the apparent size of objects decreases, and vice versa. pub scale: f32, - /// The distance of the left side of the projection from `viewport_origin` in world units. + /// The area that the projection covers. /// /// This value is automatically updated and shouldn't be manually modified. - pub left: f32, - /// The distance of the right side of the projection from `viewport_origin` in world units. - /// - /// This value is automatically updated and shouldn't be manually modified. - pub right: f32, - /// The distance of the bottom side of the projection from `viewport_origin` in world units. - /// - /// This value is automatically updated and shouldn't be manually modified. - pub bottom: f32, - /// The distance of the top side of the projection from `viewport_origin` in world units. - /// - /// This value is automatically updated and shouldn't be manually modified. - pub top: f32, + pub area: Rect, } impl CameraProjection for OrthographicProjection { fn get_projection_matrix(&self) -> Mat4 { Mat4::orthographic_rh( - self.left, - self.right, - self.bottom, - self.top, + self.area.min.x, + self.area.max.x, + self.area.min.y, + self.area.max.y, // NOTE: near and far are swapped to invert the depth range from [0,1] to [1,0] // This is for interoperability with pipelines using infinite reverse perspective projections. self.far, @@ -297,13 +285,15 @@ impl CameraProjection for OrthographicProjection { ScalingMode::Fixed { width, height } => (width, height), }; - let origin_x = projection_width * self.viewport_origin.0; - let origin_y = projection_height * self.viewport_origin.1; + let origin_x = projection_width * self.viewport_origin.x; + let origin_y = projection_height * self.viewport_origin.y; - self.left = -origin_x * self.scale; - self.bottom = -origin_y * self.scale; - self.right = (projection_width - origin_x) * self.scale; - self.top = (projection_height - origin_y) * self.scale; + self.area = Rect::new( + self.scale * -origin_x, + self.scale * -origin_y, + self.scale * projection_width - origin_x, + self.scale * projection_height - origin_y, + ); } fn far(&self) -> f32 { @@ -314,15 +304,12 @@ impl CameraProjection for OrthographicProjection { impl Default for OrthographicProjection { fn default() -> Self { OrthographicProjection { - left: -1.0, - right: 1.0, - bottom: -1.0, - top: 1.0, scale: 1.0, near: 0.0, far: 1000.0, - viewport_origin: (0.5, 0.5), + viewport_origin: Vec2::new(0.5, 0.5), scaling_mode: ScalingMode::WindowSize(1.0), + area: Rect::new(-1.0, -1.0, 1.0, 1.0), } } } From c2fa54d4e71e116cf8200d63f1f5a3d12b2022d7 Mon Sep 17 00:00:00 2001 From: Kyle Huang Date: Thu, 17 Nov 2022 20:30:42 -0700 Subject: [PATCH 12/19] Fix incorrect area calculation --- crates/bevy_render/src/camera/projection.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 576401d4d9d8c..488d1b10f8dc3 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -291,8 +291,8 @@ impl CameraProjection for OrthographicProjection { self.area = Rect::new( self.scale * -origin_x, self.scale * -origin_y, - self.scale * projection_width - origin_x, - self.scale * projection_height - origin_y, + self.scale * (projection_width - origin_x), + self.scale * (projection_height - origin_y), ); } From 9f8a4534e690d1cd6c2a0b3627db8a880020daee Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Wed, 7 Dec 2022 13:36:41 -0700 Subject: [PATCH 13/19] Specify default values in docs --- crates/bevy_render/src/camera/projection.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 488d1b10f8dc3..f18b3b6f55357 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -206,10 +206,14 @@ pub struct OrthographicProjection { /// The distance of the near clipping plane in world units. /// /// Objects closer than this will not be rendered. + /// + /// Defaults to `0.0` pub near: f32, /// The distance of the far clipping plane in world units. /// /// Objects further than this will not be rendered. + /// + /// Defaults to `1000.0` pub far: f32, /// Specifies the origin of the viewport as a normalized position from 0 to 1, where (0, 0) is the bottom left /// and (1, 1) is the top right. This determines where the camera's position sits inside the viewport. @@ -222,12 +226,18 @@ pub struct OrthographicProjection { /// Consequently, this is pivot point when scaling. With a bottom left pivot, the projection will expand /// upwards and to the right. With a top right pivot, the projection will expand downwards and to the left. /// Values in between will caused the projection to scale proportionally on each axis. + /// + /// Defaults to `(0.5, 0.5)` pub viewport_origin: Vec2, /// How the projection will scale when the viewport is resized. + /// + /// Defaults to `ScalingMode::WindowScale(1.0)` pub scaling_mode: ScalingMode, /// Scales the projection in world units. /// /// As scale increases, the apparent size of objects decreases, and vice versa. + /// + /// Defaults to `1.0` pub scale: f32, /// The area that the projection covers. /// From 02c7abe863363c5d892805a91096efe840bc2d4e Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Wed, 7 Dec 2022 15:54:55 -0700 Subject: [PATCH 14/19] Fix unused imports --- crates/bevy_render/src/camera/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index cdd26a36c638a..7bc95b0acef4d 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -7,7 +7,11 @@ pub use camera::*; pub use camera_driver_node::*; pub use projection::*; -use crate::{render_graph::RenderGraph, ExtractSchedule, RenderApp}; +use crate::{ + render_graph::RenderGraph, + view::{ComputedVisibility, Visibility, VisibleEntities}, + ExtractSchedule, RenderApp, RenderStage, +}; use bevy_app::{App, Plugin}; #[derive(Default)] From 4cf18cc41a0773c4995c9d18504a81678011a41b Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Tue, 13 Dec 2022 13:05:43 -0700 Subject: [PATCH 15/19] Fix shadow projection in examples --- crates/bevy_pbr/src/light.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index 5e1fe8a74a8b0..a3566a2c2ad85 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use bevy_ecs::prelude::*; -use bevy_math::{Mat4, UVec2, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles, Vec4, Vec4Swizzles}; +use bevy_math::{Mat4, Rect, UVec2, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles, Vec4, Vec4Swizzles}; use bevy_reflect::prelude::*; use bevy_render::{ camera::Camera, From cb4ce16e8b400828adb15da0c44fc8a45cf86f68 Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Fri, 30 Dec 2022 00:13:34 -0700 Subject: [PATCH 16/19] Update docs --- crates/bevy_render/src/camera/projection.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index f18b3b6f55357..696709d623dc1 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -193,13 +193,13 @@ pub enum ScalingMode { } /// Project a 3D space onto a 2D surface using parallel lines, i.e., unlike [`PerspectiveProjection`], -/// the size of objects remain the same regardless of their distance to camera. +/// the size of objects remains the same regardless of their distance to the camera. /// /// The volume contained in the projection is called the *view frustum*. Since the viewport is rectangular /// and projection lines are parallel, the view frustum takes the shape of a rectangular prism. /// /// Note that the scale of the projection and the apparent size of objects are inversely proportional. -/// As the size of the projection increases, the apparent size of objects decreases. +/// As the size of the projection increases, the size of objects decreases. #[derive(Component, Debug, Clone, Reflect, FromReflect)] #[reflect(Component, Default)] pub struct OrthographicProjection { @@ -217,17 +217,16 @@ pub struct OrthographicProjection { pub far: f32, /// Specifies the origin of the viewport as a normalized position from 0 to 1, where (0, 0) is the bottom left /// and (1, 1) is the top right. This determines where the camera's position sits inside the viewport. - /// Set this to (0.5, 0.5) to make scaling affect opposite sides equally, thereby keeping centered objects on each axis centered. /// - /// When the projection scales due to viewport resizing (assuming `scaling_mode` is not set to `Fixed`), the position - /// of the camera doesn't change, and since `viewport_origin` specifies the point on the viewport where the camera sits, - /// this point will always remain at the same position (relative on the viewport). + /// When the projection scales due to viewport resizing, the position of the camera, and thereby `viewport_origin`, + /// remains at the same relative point. /// /// Consequently, this is pivot point when scaling. With a bottom left pivot, the projection will expand /// upwards and to the right. With a top right pivot, the projection will expand downwards and to the left. /// Values in between will caused the projection to scale proportionally on each axis. /// - /// Defaults to `(0.5, 0.5)` + /// Defaults to `(0.5, 0.5)`, which makes scaling affect opposite sides equally, keeping the center + /// point of the viewport centered. pub viewport_origin: Vec2, /// How the projection will scale when the viewport is resized. /// @@ -239,9 +238,13 @@ pub struct OrthographicProjection { /// /// Defaults to `1.0` pub scale: f32, - /// The area that the projection covers. + /// The area that the projection covers relative to `viewport_origin`. /// - /// This value is automatically updated and shouldn't be manually modified. + /// Bevy's [`camera_system`](crate::camera::camera_system) automatically + /// updates this value when the viewport is resized depending on `OrthographicProjection`'s other fields. + /// In this case, `area` should not be manually modified. + /// + /// It may be necessary to set this manually for shadow projections and such. pub area: Rect, } From de6890fd9c087e20d9b6fc061214fff791804d0b Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Wed, 18 Jan 2023 13:24:43 -0700 Subject: [PATCH 17/19] Update docs wording --- crates/bevy_render/src/camera/projection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 696709d623dc1..93f0792642b92 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -196,7 +196,7 @@ pub enum ScalingMode { /// the size of objects remains the same regardless of their distance to the camera. /// /// The volume contained in the projection is called the *view frustum*. Since the viewport is rectangular -/// and projection lines are parallel, the view frustum takes the shape of a rectangular prism. +/// and projection lines are parallel, the view frustum takes the shape of a cuboid. /// /// Note that the scale of the projection and the apparent size of objects are inversely proportional. /// As the size of the projection increases, the size of objects decreases. From 0dcd50174ad3e0697ba307440e119f1a78865a09 Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Wed, 8 Feb 2023 13:07:25 -0700 Subject: [PATCH 18/19] Fix unused imports --- crates/bevy_pbr/src/light.rs | 2 +- crates/bevy_render/src/camera/mod.rs | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index a3566a2c2ad85..5e1fe8a74a8b0 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use bevy_ecs::prelude::*; -use bevy_math::{Mat4, Rect, UVec2, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles, Vec4, Vec4Swizzles}; +use bevy_math::{Mat4, UVec2, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles, Vec4, Vec4Swizzles}; use bevy_reflect::prelude::*; use bevy_render::{ camera::Camera, diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index 7bc95b0acef4d..cdd26a36c638a 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -7,11 +7,7 @@ pub use camera::*; pub use camera_driver_node::*; pub use projection::*; -use crate::{ - render_graph::RenderGraph, - view::{ComputedVisibility, Visibility, VisibleEntities}, - ExtractSchedule, RenderApp, RenderStage, -}; +use crate::{render_graph::RenderGraph, ExtractSchedule, RenderApp}; use bevy_app::{App, Plugin}; #[derive(Default)] From 386dd25e5cea74ecb2ed390507dc231a0637a74c Mon Sep 17 00:00:00 2001 From: Kewei Huang Date: Wed, 8 Feb 2023 14:19:30 -0700 Subject: [PATCH 19/19] Remove empty scene_viewer.rs --- examples/tools/scene_viewer.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/tools/scene_viewer.rs diff --git a/examples/tools/scene_viewer.rs b/examples/tools/scene_viewer.rs deleted file mode 100644 index e69de29bb2d1d..0000000000000