Skip to content

Commit

Permalink
3D OrthographicProjection improvements + new example (#1361)
Browse files Browse the repository at this point in the history
* use `length_squared` for visible entities

* ortho projection 2d/3d different depth calculation

* use ScalingMode::FixedVertical for 3d ortho

* new example: 3d orthographic
  • Loading branch information
inodentry authored Feb 1, 2021
1 parent 83e30a8 commit 7d065ee
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 7 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ path = "examples/3d/load_gltf.rs"
name = "msaa"
path = "examples/3d/msaa.rs"

[[example]]
name = "orthographic"
path = "examples/3d/orthographic.rs"

[[example]]
name = "parenting"
path = "examples/3d/parenting.rs"
Expand Down
8 changes: 6 additions & 2 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use super::CameraProjection;
use bevy_app::prelude::EventReader;
use bevy_ecs::{Added, Component, Entity, Query, QuerySet, Res};
use bevy_math::{Mat4, Vec2, Vec3};
use bevy_reflect::{Reflect, ReflectComponent};
use bevy_reflect::{Reflect, ReflectComponent, ReflectDeserialize};
use bevy_transform::components::GlobalTransform;
use bevy_window::{WindowCreated, WindowId, WindowResized, Windows};
use serde::{Deserialize, Serialize};

#[derive(Default, Debug, Reflect)]
#[reflect(Component)]
Expand All @@ -17,9 +18,12 @@ pub struct Camera {
pub depth_calculation: DepthCalculation,
}

#[derive(Debug)]
#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize)]
#[reflect_value(Serialize, Deserialize)]
pub enum DepthCalculation {
/// Pythagorean distance; works everywhere, more expensive to compute.
Distance,
/// Optimization for 2D; assuming the camera points towards -Z.
ZDifference,
}

Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_render/src/camera/projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub struct OrthographicProjection {
pub window_origin: WindowOrigin,
pub scaling_mode: ScalingMode,
pub scale: f32,
pub depth_calculation: DepthCalculation,
}

impl CameraProjection for OrthographicProjection {
Expand Down Expand Up @@ -140,7 +141,7 @@ impl CameraProjection for OrthographicProjection {
}

fn depth_calculation(&self) -> DepthCalculation {
DepthCalculation::ZDifference
self.depth_calculation
}
}

Expand All @@ -156,6 +157,7 @@ impl Default for OrthographicProjection {
window_origin: WindowOrigin::Center,
scaling_mode: ScalingMode::WindowSize,
scale: 1.0,
depth_calculation: DepthCalculation::Distance,
}
}
}
2 changes: 1 addition & 1 deletion crates/bevy_render/src/camera/visible_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ pub fn visible_entities_system(
// smaller distances are sorted to lower indices by using the distance from the camera
FloatOrd(match camera.depth_calculation {
DepthCalculation::ZDifference => camera_position.z - position.z,
DepthCalculation::Distance => (camera_position - position).length(),
DepthCalculation::Distance => (camera_position - position).length_squared(),
})
} else {
let order = FloatOrd(no_transform_order);
Expand Down
12 changes: 10 additions & 2 deletions crates/bevy_render/src/entity.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::{
camera::{Camera, OrthographicProjection, PerspectiveProjection, VisibleEntities},
camera::{
Camera, DepthCalculation, OrthographicProjection, PerspectiveProjection, ScalingMode,
VisibleEntities,
},
pipeline::RenderPipelines,
prelude::Visible,
render_graph::base,
Expand Down Expand Up @@ -92,6 +95,7 @@ impl OrthographicCameraBundle {
},
orthographic_projection: OrthographicProjection {
far,
depth_calculation: DepthCalculation::ZDifference,
..Default::default()
},
visible_entities: Default::default(),
Expand All @@ -106,7 +110,11 @@ impl OrthographicCameraBundle {
name: Some(base::camera::CAMERA_3D.to_string()),
..Default::default()
},
orthographic_projection: Default::default(),
orthographic_projection: OrthographicProjection {
scaling_mode: ScalingMode::FixedVertical,
depth_calculation: DepthCalculation::Distance,
..Default::default()
},
visible_entities: Default::default(),
transform: Default::default(),
global_transform: Default::default(),
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ui/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
use bevy_asset::Handle;
use bevy_ecs::Bundle;
use bevy_render::{
camera::{Camera, OrthographicProjection, VisibleEntities, WindowOrigin},
camera::{Camera, DepthCalculation, OrthographicProjection, VisibleEntities, WindowOrigin},
draw::Draw,
mesh::Mesh,
pipeline::{RenderPipeline, RenderPipelines},
Expand Down Expand Up @@ -185,6 +185,7 @@ impl Default for UiCameraBundle {
orthographic_projection: OrthographicProjection {
far,
window_origin: WindowOrigin::BottomLeft,
depth_calculation: DepthCalculation::ZDifference,
..Default::default()
},
visible_entities: Default::default(),
Expand Down
62 changes: 62 additions & 0 deletions examples/3d/orthographic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use bevy::prelude::*;

fn main() {
App::build()
.insert_resource(Msaa { samples: 4 })
.add_plugins(DefaultPlugins)
.add_startup_system(setup.system())
.run();
}

/// set up a simple 3D scene
fn setup(
commands: &mut Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// set up the camera
let mut camera = OrthographicCameraBundle::new_3d();
camera.orthographic_projection.scale = 3.0;
camera.transform = Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::zero(), Vec3::unit_y());

// add entities to the world
commands
// plane
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..Default::default()
})
// cubes
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(1.5, 0.5, 1.5),
..Default::default()
})
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(1.5, 0.5, -1.5),
..Default::default()
})
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(-1.5, 0.5, 1.5),
..Default::default()
})
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(-1.5, 0.5, -1.5),
..Default::default()
})
// light
.spawn(LightBundle {
transform: Transform::from_xyz(3.0, 8.0, 5.0),
..Default::default()
})
// camera
.spawn(camera);
}
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Example | File | Description
`3d_scene` | [`3d/3d_scene.rs`](./3d/3d_scene.rs) | Simple 3D scene with basic shapes and lighting
`load_gltf` | [`3d/load_gltf.rs`](./3d/load_gltf.rs) | Loads and renders a gltf file as a scene
`msaa` | [`3d/msaa.rs`](./3d/msaa.rs) | Configures MSAA (Multi-Sample Anti-Aliasing) for smoother edges
`orthographic` | [`3d/orthographic.rs`](./3d/orthographic.rs) | Shows how to create a 3D orthographic view (for isometric-look games or CAD applications)
`parenting` | [`3d/parenting.rs`](./3d/parenting.rs) | Demonstrates parent->child relationships and relative transformations
`spawner` | [`3d/spawner.rs`](./3d/spawner.rs) | Renders a large number of cubes with changing position and material
`texture` | [`3d/texture.rs`](./3d/texture.rs) | Shows configuration of texture materials
Expand Down

0 comments on commit 7d065ee

Please sign in to comment.