Ignore inactive cameras (#10543)

# Objective

Currently, if a large amount of inactive cameras are spawned, they will
immensely slow down performance.

This can be reproduced by adding

```rust
    let default_image = images.add(default());
    for _ in 0..10000 {
        commands.spawn(Camera3dBundle {
            camera: Camera {
                is_active: false,
                target: RenderTarget::Image(default_image.clone()),
                ..default()
            },
            ..default()
        });
    }
```

to for example `3d_shapes`.

Using `tracy`, it's clear that preparing view bind groups for all
cameras is still happening.
Also, visibility checks on the extracted views from inactive cameras
also take place.

## Performance gains

The following `tracy` comparisons show the effect of skipping this
unneeded work.
Yellow is Bevy main, red is with the fix.

### Visibility checks


![bevy-visibility-check-savings](https://github.com/bevyengine/bevy/assets/52322338/154a20ce-bd70-487e-a85c-8b993950ea2b)

### Bind group preparation


![bevy-mesh2d-savings](https://github.com/bevyengine/bevy/assets/52322338/a48d8d9a-8c37-4c34-9698-b1b1bf01f070)


## Solution

- Check if the cameras are inactive in the appropriate places, and if so
skip them

## Changelog

### Changed

- Do not extract views from inactive cameras or check visiblity from
their extracted views

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
This commit is contained in:
Torstein Grindvik 2023-11-14 03:13:21 +01:00 committed by GitHub
parent 713b1d8fa4
commit 74c97332a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 2 deletions

View File

@ -384,7 +384,12 @@ fn reset_view_visibility(mut query: Query<&mut ViewVisibility>) {
/// for that view.
pub fn check_visibility(
mut thread_queues: Local<ThreadLocal<Cell<Vec<Entity>>>>,
mut view_query: Query<(&mut VisibleEntities, &Frustum, Option<&RenderLayers>), With<Camera>>,
mut view_query: Query<(
&mut VisibleEntities,
&Frustum,
Option<&RenderLayers>,
&Camera,
)>,
mut visible_aabb_query: Query<(
Entity,
&InheritedVisibility,
@ -395,7 +400,11 @@ pub fn check_visibility(
Has<NoFrustumCulling>,
)>,
) {
for (mut visible_entities, frustum, maybe_view_mask) in &mut view_query {
for (mut visible_entities, frustum, maybe_view_mask, camera) in &mut view_query {
if !camera.is_active {
continue;
}
let view_mask = maybe_view_mask.copied().unwrap_or_default();
visible_entities.entities.clear();

View File

@ -551,6 +551,11 @@ pub fn extract_default_ui_camera_view<T: Component>(
if matches!(camera_ui, Some(&UiCameraConfig { show_ui: false, .. })) {
continue;
}
// ignore inactive cameras
if !camera.is_active {
continue;
}
if let (
Some(logical_size),
Some(URect {