custom_projection/
custom_projection.rs1use bevy::prelude::*;
4use bevy::render::camera::CameraProjection;
5
6fn main() {
7 App::new()
8 .add_plugins(DefaultPlugins)
9 .add_systems(Startup, setup)
10 .run();
11}
12
13#[derive(Debug, Clone)]
15struct ObliquePerspectiveProjection {
16 horizontal_obliqueness: f32,
17 vertical_obliqueness: f32,
18 perspective: PerspectiveProjection,
19}
20
21impl CameraProjection for ObliquePerspectiveProjection {
23 fn get_clip_from_view(&self) -> Mat4 {
24 let mut mat = self.perspective.get_clip_from_view();
25 mat.col_mut(2)[0] = self.horizontal_obliqueness;
26 mat.col_mut(2)[1] = self.vertical_obliqueness;
27 mat
28 }
29
30 fn get_clip_from_view_for_sub(&self, sub_view: &bevy_render::camera::SubCameraView) -> Mat4 {
31 let mut mat = self.perspective.get_clip_from_view_for_sub(sub_view);
32 mat.col_mut(2)[0] = self.horizontal_obliqueness;
33 mat.col_mut(2)[1] = self.vertical_obliqueness;
34 mat
35 }
36
37 fn update(&mut self, width: f32, height: f32) {
38 self.perspective.update(width, height);
39 }
40
41 fn far(&self) -> f32 {
42 self.perspective.far
43 }
44
45 fn get_frustum_corners(&self, z_near: f32, z_far: f32) -> [Vec3A; 8] {
46 self.perspective.get_frustum_corners(z_near, z_far)
47 }
48}
49
50fn setup(
51 mut commands: Commands,
52 mut meshes: ResMut<Assets<Mesh>>,
53 mut materials: ResMut<Assets<StandardMaterial>>,
54) {
55 commands.spawn((
56 Camera3d::default(),
57 Projection::custom(ObliquePerspectiveProjection {
59 horizontal_obliqueness: 0.2,
60 vertical_obliqueness: 0.6,
61 perspective: PerspectiveProjection::default(),
62 }),
63 Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
64 ));
65
66 commands.spawn((
68 Mesh3d(meshes.add(Circle::new(4.0))),
69 MeshMaterial3d(materials.add(Color::WHITE)),
70 Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
71 ));
72 commands.spawn((
73 Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
74 MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
75 Transform::from_xyz(0.0, 0.5, 0.0),
76 ));
77 commands.spawn((
78 PointLight {
79 shadows_enabled: true,
80 ..default()
81 },
82 Transform::from_xyz(4.0, 8.0, 4.0),
83 ));
84}