-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove the type parameter from check_visibility
, and only invoke it once.
#16812
base: main
Are you sure you want to change the base?
Conversation
once. Currently, `check_visibility` is parameterized over a query filter that specifies the type of potentially-visible object. This has the unfortunate side effect that we need a separate system, `mark_view_visibility_as_changed_if_necessary`, to trigger view visibility change detection. That system is quite slow because it must iterate sequentially over all entities in the scene. This PR moves the query filter from `check_visibility` to a new component, `VisibilityClass`. `VisibilityClass` stores a list of type IDs, each corresponding to one of the query filters we used to use. Because `check_visibility` is no longer specialized to the query filter at the type level, Bevy now only needs to invoke it once, leading to better performance as `check_visibility` can do change detection on the fly rather than delegating it to a separate system. This commit also has ergonomic improvements, as there's no need for applications that want to add their own custom renderable components to add specializations of the `check_visibility` system to the schedule. Instead, they only need to ensure that the `ViewVisibility` component is properly kept up to date. The recommended way to do this, and the way that's demonstrated in the `custom_phase_item` and `specialized_mesh_pipeline` examples, is to make `ViewVisibility` a required component and to add the type ID to it in a component add hook. This patch does this for `Mesh3d`, `Mesh2d`, `Sprite`, `Light`, and `Node`, which means that most app code doesn't need to change at all. Note that, although this patch has a large impact on the performance of visibility determination, it doesn't actually improve the end-to-end frame time of `many_cubes`. That's because the render world was already effectively hiding the latency from `mark_view_visibility_as_changed_if_necessary`. This patch is, however, necessary for *further* improvements to `many_cubes` performance.
/// add-component hook that adds the type ID of that component to the | ||
/// [`VisibilityClass`] array. See `custom_phase_item` for an example. | ||
#[derive(Clone, Component, Default, Reflect, Deref, DerefMut)] | ||
pub struct VisibilityClass(pub SmallVec<[TypeId; 1]>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much more work would it be to store ComponentId
instead of TypeId
? The former would be more introspect-able.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ItsDoot I just tried it, and unfortunately it's not really possible because those IDs get fed into the render world, and component IDs are per-world.
@pcwalton need to do the same for MeshletMesh3d, conditionally when the MeshletPlugin is loaded. |
@JMS55 Good point, added meshlet support. |
Currently,
check_visibility
is parameterized over a query filter that specifies the type of potentially-visible object. This has the unfortunate side effect that we need a separate system,mark_view_visibility_as_changed_if_necessary
, to trigger view visibility change detection. That system is quite slow because it must iterate sequentially over all entities in the scene.This PR moves the query filter from
check_visibility
to a new component,VisibilityClass
.VisibilityClass
stores a list of type IDs, each corresponding to one of the query filters we used to use. Becausecheck_visibility
is no longer specialized to the query filter at the type level, Bevy now only needs to invoke it once, leading to better performance ascheck_visibility
can do change detection on the fly rather than delegating it to a separate system.This commit also has ergonomic improvements, as there's no need for applications that want to add their own custom renderable components to add specializations of the
check_visibility
system to the schedule. Instead, they only need to ensure that theViewVisibility
component is properly kept up to date. The recommended way to do this, and the way that's demonstrated in thecustom_phase_item
andspecialized_mesh_pipeline
examples, is to makeViewVisibility
a required component and to add the type ID to it in a component add hook. This patch does this forMesh3d
,Mesh2d
,Sprite
,Light
, andNode
, which means that most app code doesn't need to change at all.Note that, although this patch has a large impact on the performance of visibility determination, it doesn't actually improve the end-to-end frame time of
many_cubes
. That's because the render world was already effectively hiding the latency frommark_view_visibility_as_changed_if_necessary
. This patch is, however, necessary for further improvements tomany_cubes
performance.many_cubes
trace before:many_cubes
trace after:Migration Guide
check_visibility
no longer takes aQueryFilter
, and there's no need to add it manually to your app schedule anymore for custom rendering items. Instead, entities with custom renderable components should add the appropriate type IDs toVisibilityClass
. Seecustom_phase_item
for an example.