Skip to content

Changing the Viewport of a camera doesn't update its projection #5944

@jakobhellermann

Description

@jakobhellermann

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.

if camera
.target
.is_changed(&changed_window_ids, &changed_image_handles)
|| added_cameras.contains(&entity)
|| camera_projection.is_changed()
{
camera.computed.target_info = camera.target.get_render_target_info(&windows, &images);
if let Some(size) = camera.logical_viewport_size() {
camera_projection.update(size.x, size.y);
camera.computed.projection_matrix = camera_projection.get_projection_matrix();
}
}
}

How to solve this

I can think of two solutions.

  1. we add || camera.is_changed(), relying on change detection.
    This is overly sensitive as this would also return true if someone changed is_active or priority, or if someone mistakenly had a unused deref_mut somewhere.
  2. keep track of the old viewport in the computed_state, and if camera.viewport != camera.computed_state.old_viewport, then update the projection. This is more reliable, but needs to store two UVec2s more in the camera (probably not a big deal).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions