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

### Bind group preparation

## 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:
		
							parent
							
								
									713b1d8fa4
								
							
						
					
					
						commit
						74c97332a6
					
				@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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 {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user