From ac9b0c848cb9e27ff31162353d03216b067a0669 Mon Sep 17 00:00:00 2001 From: m-edlund Date: Sat, 5 Oct 2024 03:36:47 +0200 Subject: [PATCH] fix: corrected projection calculation of camera sub view (#15646) # Objective - Fixes #15600 ## Solution - The projection calculations did not use the aspect ratio of `full_size`, this was amended ## Testing - I created a test example on [this fork](https://github.com/m-edlund/bevy/tree/bug/main/subViewProjectionBroken) to allow testing with different aspect ratios and offsets - The sub view is bound to a view port that can move across the screen. The image in the moving sub view should "match" the full image exactly ## Showcase Current version: https://github.com/user-attachments/assets/17ad1213-d5ae-4181-89c1-81146edede7d Fixed version: https://github.com/user-attachments/assets/398e0927-e1dd-4880-897d-8157aa4398e6 --- crates/bevy_render/src/camera/projection.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index 832ba6e56f0bf..e29d4ec869d8e 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -206,10 +206,12 @@ impl CameraProjection for PerspectiveProjection { // Y-axis increases from top to bottom let offset_y = full_height - (sub_view.offset.y + sub_height); + let full_aspect = full_width / full_height; + // Original frustum parameters let top = self.near * ops::tan(0.5 * self.fov); let bottom = -top; - let right = top * self.aspect_ratio; + let right = top * full_aspect; let left = -right; // Calculate scaling factors @@ -450,11 +452,18 @@ impl CameraProjection for OrthographicProjection { let sub_width = sub_view.size.x as f32; let sub_height = sub_view.size.y as f32; - // Orthographic projection parameters + let full_aspect = full_width / full_height; + + // Base the vertical size on self.area and adjust the horizontal size let top = self.area.max.y; let bottom = self.area.min.y; - let right = self.area.max.x; - let left = self.area.min.x; + let ortho_height = top - bottom; + let ortho_width = ortho_height * full_aspect; + + // Center the orthographic area horizontally + let center_x = (self.area.max.x + self.area.min.x) / 2.0; + let left = center_x - ortho_width / 2.0; + let right = center_x + ortho_width / 2.0; // Calculate scaling factors let scale_w = (right - left) / full_width;