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
This commit is contained in:
m-edlund 2024-10-05 03:36:47 +02:00 committed by GitHub
parent 2e89e98931
commit ac9b0c848c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -206,10 +206,12 @@ impl CameraProjection for PerspectiveProjection {
// Y-axis increases from top to bottom // Y-axis increases from top to bottom
let offset_y = full_height - (sub_view.offset.y + sub_height); let offset_y = full_height - (sub_view.offset.y + sub_height);
let full_aspect = full_width / full_height;
// Original frustum parameters // Original frustum parameters
let top = self.near * ops::tan(0.5 * self.fov); let top = self.near * ops::tan(0.5 * self.fov);
let bottom = -top; let bottom = -top;
let right = top * self.aspect_ratio; let right = top * full_aspect;
let left = -right; let left = -right;
// Calculate scaling factors // Calculate scaling factors
@ -450,11 +452,18 @@ impl CameraProjection for OrthographicProjection {
let sub_width = sub_view.size.x as f32; let sub_width = sub_view.size.x as f32;
let sub_height = sub_view.size.y 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 top = self.area.max.y;
let bottom = self.area.min.y; let bottom = self.area.min.y;
let right = self.area.max.x; let ortho_height = top - bottom;
let left = self.area.min.x; 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 // Calculate scaling factors
let scale_w = (right - left) / full_width; let scale_w = (right - left) / full_width;