bevy/crates
Carter Anderson 40d4992401 Visibilty Inheritance, universal ComputedVisibility and RenderLayers support (#5310)
# Objective

Fixes #4907. Fixes #838. Fixes #5089.
Supersedes #5146. Supersedes #2087. Supersedes #865. Supersedes #5114

Visibility is currently entirely local. Set a parent entity to be invisible, and the children are still visible. This makes it hard for users to hide entire hierarchies of entities.

Additionally, the semantics of `Visibility` vs `ComputedVisibility` are inconsistent across entity types. 3D meshes use `ComputedVisibility` as the "definitive" visibility component, with `Visibility` being just one data source. Sprites just use `Visibility`, which means they can't feed off of `ComputedVisibility` data, such as culling information, RenderLayers, and (added in this pr) visibility inheritance information.

## Solution

Splits `ComputedVisibilty::is_visible` into `ComputedVisibilty::is_visible_in_view` and `ComputedVisibilty::is_visible_in_hierarchy`. For each visible entity, `is_visible_in_hierarchy` is computed by propagating visibility down the hierarchy. The `ComputedVisibility::is_visible()` function combines these two booleans for the canonical "is this entity visible" function.

Additionally, all entities that have `Visibility` now also have `ComputedVisibility`.  Sprites, Lights, and UI entities now use `ComputedVisibility` when appropriate.

This means that in addition to visibility inheritance, everything using Visibility now also supports RenderLayers. Notably, Sprites (and other 2d objects) now support `RenderLayers` and work properly across multiple views.

Also note that this does increase the amount of work done per sprite. Bevymark with 100,000 sprites on `main` runs in `0.017612` seconds and this runs in `0.01902`. That is certainly a gap, but I believe the api consistency and extra functionality this buys us is worth it. See [this thread](https://github.com/bevyengine/bevy/pull/5146#issuecomment-1182783452) for more info. Note that #5146 in combination with #5114 _are_ a viable alternative to this PR and _would_ perform better, but that comes at the cost of api inconsistencies and doing visibility calculations in the "wrong" place. The current visibility system does have potential for performance improvements. I would prefer to evolve that one system as a whole rather than doing custom hacks / different behaviors for each feature slice.

Here is a "split screen" example where the left camera uses RenderLayers to filter out the blue sprite.

![image](https://user-images.githubusercontent.com/2694663/178814868-2e9a2173-bf8c-4c79-8815-633899d492c3.png)


Note that this builds directly on #5146 and that @james7132 deserves the credit for the baseline visibility inheritance work. This pr moves the inherited visibility field into `ComputedVisibility`, then does the additional work of porting everything to `ComputedVisibility`. See my [comments here](https://github.com/bevyengine/bevy/pull/5146#issuecomment-1182783452) for rationale. 

## Follow up work

* Now that lights use ComputedVisibility, VisibleEntities now includes "visible lights" in the entity list. Functionally not a problem as we use queries to filter the list down in the desired context. But we should consider splitting this out into a separate`VisibleLights` collection for both clarity and performance reasons. And _maybe_ even consider scoping `VisibleEntities` down to `VisibleMeshes`?.
* Investigate alternative sprite rendering impls (in combination with visibility system tweaks) that avoid re-generating a per-view fixedbitset of visible entities every frame, then checking each ExtractedEntity. This is where most of the performance overhead lives. Ex: we could generate ExtractedEntities per-view using the VisibleEntities list, avoiding the need for the bitset.
* Should ComputedVisibility use bitflags under the hood? This would cut down on the size of the component, potentially speed up the `is_visible()` function, and allow us to cheaply expand ComputedVisibility with more data (ex: split out local visibility and parent visibility, add more culling classes, etc).
---

## Changelog

* ComputedVisibility now takes hierarchy visibility into account.
* 2D, UI and Light entities now use the ComputedVisibility component.

## Migration Guide

If you were previously reading `Visibility::is_visible` as the "actual visibility" for sprites or lights, use `ComputedVisibilty::is_visible()` instead:

```rust
// before (0.7)
fn system(query: Query<&Visibility>) {
  for visibility in query.iter() {
    if visibility.is_visible {
       log!("found visible entity");
    }
  }
}

// after (0.8)
fn system(query: Query<&ComputedVisibility>) {
  for visibility in query.iter() {
    if visibility.is_visible() {
       log!("found visible entity");
    }
  }
}
``` 


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-15 23:24:42 +00:00
..
bevy_animation Update codebase to use IntoIterator where possible. (#5269) 2022-07-11 15:28:50 +00:00
bevy_app Simplify design for *Labels (#4957) 2022-07-14 18:23:01 +00:00
bevy_asset update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
bevy_audio update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
bevy_core Export and register Mat2. (#5324) 2022-07-15 22:37:06 +00:00
bevy_core_pipeline update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
bevy_derive android - fix issues other than the rendering (#5130) 2022-06-30 19:42:45 +00:00
bevy_diagnostic Cleanups in diagnostics (#3871) 2022-06-20 17:02:25 +00:00
bevy_dylib Bump Bevy to 0.8.0-dev (#4505) 2022-04-17 23:04:52 +00:00
bevy_dynamic_plugin Bump Bevy to 0.8.0-dev (#4505) 2022-04-17 23:04:52 +00:00
bevy_ecs Simplify design for *Labels (#4957) 2022-07-14 18:23:01 +00:00
bevy_ecs_compile_fail_tests Add ExactSizeIterator implementation for QueryCombinatonIter (#5148) 2022-07-13 16:08:48 +00:00
bevy_encase_derive Updated glam to 0.21. (#5142) 2022-07-03 19:55:33 +00:00
bevy_gilrs Improve Gamepad DPad Button Detection (#5220) 2022-07-11 14:11:25 +00:00
bevy_gltf Allow rendering meshes without UV coordinate data. (#5222) 2022-07-08 20:55:08 +00:00
bevy_hierarchy Update codebase to use IntoIterator where possible. (#5269) 2022-07-11 15:28:50 +00:00
bevy_input Implement Debug for Gamepads (#5291) 2022-07-13 15:10:41 +00:00
bevy_internal enable optional dependencies to stay optional (#5023) 2022-06-20 10:32:43 +00:00
bevy_log Remove the dependency cycles (#5171) 2022-07-04 13:04:18 +00:00
bevy_macro_utils Simplify design for *Labels (#4957) 2022-07-14 18:23:01 +00:00
bevy_math Export and register Mat2. (#5324) 2022-07-15 22:37:06 +00:00
bevy_mikktspace Updated glam to 0.21. (#5142) 2022-07-03 19:55:33 +00:00
bevy_pbr Visibilty Inheritance, universal ComputedVisibility and RenderLayers support (#5310) 2022-07-15 23:24:42 +00:00
bevy_ptr add more SAFETY comments and lint for missing ones in bevy_ecs (#4835) 2022-07-04 14:44:24 +00:00
bevy_reflect update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
bevy_render Visibilty Inheritance, universal ComputedVisibility and RenderLayers support (#5310) 2022-07-15 23:24:42 +00:00
bevy_scene Update codebase to use IntoIterator where possible. (#5269) 2022-07-11 15:28:50 +00:00
bevy_sprite Visibilty Inheritance, universal ComputedVisibility and RenderLayers support (#5310) 2022-07-15 23:24:42 +00:00
bevy_tasks Very minor doc formatting changes (#5287) 2022-07-12 13:06:16 +00:00
bevy_text Visibilty Inheritance, universal ComputedVisibility and RenderLayers support (#5310) 2022-07-15 23:24:42 +00:00
bevy_time Update time by sending frame instant through a channel (#4744) 2022-07-11 23:19:00 +00:00
bevy_transform Fix incorrect rotation in Transform::rotate_around. (#5300) 2022-07-13 15:10:43 +00:00
bevy_ui Visibilty Inheritance, universal ComputedVisibility and RenderLayers support (#5310) 2022-07-15 23:24:42 +00:00
bevy_utils Simplify design for *Labels (#4957) 2022-07-14 18:23:01 +00:00
bevy_window update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
bevy_winit Change window position types from tuple to vec (#5276) 2022-07-11 14:36:23 +00:00