bevy
bevy copied to clipboard
Changing the `Viewport` of a camera doesn't update its projection
Bevy version
main (6f2cc0b30e335f3084f7028498c0866279c78099
What you did
cam.viewport = Some(Viewport {
physical_position: UVec2::new(viewport_pos.x as u32, viewport_pos.y as u32),
physical_size: UVec2::new(viewport_size.x as u32, viewport_size.y as u32),
depth: 0.0..1.0,
});
What went wrong
The projection of the camera got messed up.
Why does this happen?
The Camera maintains some computed values, like the projection matrix Mat4 and the render target size.
This computed info is only updated if 1. the render target changed, 2. the camera got added or 3. the camera projection got changed.
Changing the viewport also changed the projection which isn't caught here.
https://github.com/bevyengine/bevy/blob/6f2cc0b30e335f3084f7028498c0866279c78099/crates/bevy_render/src/camera/camera.rs#L380-L392
How to solve this
I can think of two solutions.
- we add
|| camera.is_changed(), relying on change detection. This is overly sensitive as this would also return true if someone changedis_activeorpriority, or if someone mistakenly had a unusedderef_mutsomewhere. - keep track of the old viewport in the
computed_state, and ifcamera.viewport != camera.computed_state.old_viewport, then update the projection. This is more reliable, but needs to store twoUVec2s more in the camera (probably not a big deal).