diff --git a/src/projection.rs b/src/projection.rs index 857043a..8e3f666 100644 --- a/src/projection.rs +++ b/src/projection.rs @@ -29,8 +29,8 @@ pub fn make_projection_rh_from_frustum( Mat4::from_cols( Vec4::new(2.0 * near / (right - left), 0.0, 0.0, 0.0), Vec4::new(0.0, 2.0 * near / (top - bottom), 0.0, 0.0), - Vec4::new(a, b, c, -1.0), - Vec4::new(0.0, 0.0, d, 0.0), + Vec4::new(0.0, 0.0, c, -1.0), + Vec4::new(a, b, d, 0.0), ) } @@ -45,31 +45,35 @@ pub fn make_projection_rh_from_frustum_reversed( ) -> Mat4 { assert!(z_near > 0.0 && z_far > 0.0); - info!("near {:?}",z_near); + info!("near {:?}", z_near); // - // reversed z 0..1 projection based on https://thxforthefish.com/posts/reverse_z/ + // reversed z 0..1 projection based on https://thxforthefish.com/posts/reverse_z/ and + // https://vincent-p.github.io/posts/vulkan_perspective_matrix/ // - let a = (right + left) / (right - left); - let b = (top + bottom) / (top - bottom); - let c = z_near / (z_far - z_near); - let d = z_far * z_near / (z_far - z_near); - let sx = 2.0 * z_near / (right - left); - let sy = 2.0 * z_near / (top - bottom); + let a = (right + left) / (right - left); // position in frame horizontal + let b = (top + bottom) / (top - bottom); // position in frame vertical - // for reverse z 0..1 - // sx 0 a 0 + let c = z_near / (z_far - z_near); // lower bound + let d = z_far * z_near / (z_far - z_near); // upper bound + + let sx = 2.0 * z_near / (right - left); // scale x + let sy = 2.0 * z_near / (top - bottom); // scale y + + // reverse z 0..1 + // -------------- + // sx 0 a 0 // 0 sy b 0 // 0 0 c d // 0 0 -1 0 Mat4::from_cols( - Vec4::new(sx, 0.0, 0.0, 0.0), - Vec4::new(0.0, sy, 0.0, 0.0), - Vec4::new(0.0, 0.0, c, -1.0), - Vec4::new(a, b, d, 0.0), + Vec4::new(sx, 0.0, 0.0, 0.0), + Vec4::new(0.0, sy, 0.0, 0.0), + Vec4::new(a, b, c, -1.0), + Vec4::new(0.0, 0.0, d, 0.0), ) } @@ -130,7 +134,7 @@ pub fn create_offaxis_matrices( let bottom = vec_up_normalized.dot(frustum_left) * z_near / dist; // bottom screen edge let top = vec_up_normalized.dot(frustum_up) * z_near / dist; // distance eye from screen - info!("l r b t {} {} {} {}",left,right,bottom,top); + info!("l r b t {} {} {} {}", left, right, bottom, top); // create a view frustum let projection_matrix = @@ -166,7 +170,8 @@ pub fn create_offaxis_matrices( let view_matrix_eye = Mat4::from_cols(Vec4::X, Vec4::Y, Vec4::Z, (-pos_eye).extend(1.0)); // create resulting view matrix (this should be much simpler using glam API) - let view_matrix = view_matrix_rotation * view_matrix_eye; + let view_matrix = view_matrix_eye * view_matrix_rotation; + //view_matrix_rotation * view_matrix_eye; // info!("{:?}",view_matrix_eye); diff --git a/src/scene.rs b/src/scene.rs index 54c16e1..1541b27 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -7,7 +7,7 @@ pub fn build_scene( ) { // plane commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Plane { size: 4.0 })), + mesh: meshes.add(Mesh::from(shape::Plane { size: 2.5 })), material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), transform: Transform::from_xyz(0.0, -0.5, 0.0), ..default() @@ -16,7 +16,7 @@ pub fn build_scene( commands.spawn(PbrBundle { mesh: meshes.add(Mesh::from(shape::Cube { size: 1.5 })), material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), - transform: Transform::from_xyz(0.0, 0.5, -3.0), + transform: Transform::from_xyz(0.0, 0.5, -1.5), ..default() }); // light @@ -26,7 +26,7 @@ pub fn build_scene( shadows_enabled: true, ..default() }, - transform: Transform::from_xyz(4.0, 1.0, -4.0), + transform: Transform::from_xyz(4.0, 4.0, -1.5), ..default() }); } diff --git a/src/viewer.rs b/src/viewer.rs index dcbcd65..51f6e76 100644 --- a/src/viewer.rs +++ b/src/viewer.rs @@ -87,7 +87,7 @@ pub fn simulate_viewer_with_keyboard( for mut viewer in query.iter_mut() { if input.pressed(KeyCode::W) { viewer.position += Vec3::Z * time.delta_seconds(); - } else if (input.pressed(KeyCode::S)) { + } else if input.pressed(KeyCode::S) { viewer.position -= Vec3::Z * time.delta_seconds(); } else if input.pressed(KeyCode::A) { viewer.position -= Vec3::X * time.delta_seconds();