Static and cached marker components#11864
Closed
NthTensor wants to merge 1 commit intobevyengine:mainfrom
Closed
Conversation
BD103
reviewed
Feb 14, 2024
Comment on lines
+172
to
+175
| /// Cached is a special marker component closely related to [`Static`]. | ||
| /// | ||
| /// Systems in the [`PostUpdate`] schedule that query for cached entities should run after [`refresh_cached`] | ||
| /// to avoid a possible one frame lag when [`Static`] is removed. |
Member
There was a problem hiding this comment.
Should there be a warning against manually inserting Cached into an entity? From your description, it seems that only render extraction should be adding it.
Contributor
Author
|
This change is now stale because of recent rendering architecture improvements. I think the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
Bevy assumes all entities are entirely dynamic. This is a good default, because it encourages us to keep bevy scalable and efficient. Unfortunately this means we often waste some of our limited compute each frame re-exporting and re-processing data that hasn't actually changed.
There should be a way to mark entities that only need to be processed once without needing to rely on change detection (which is not efficient when the number of changes is small compared to the number of queried items).
Solution
Add two new table-backed marker components:
StaticandCached.Bevy assumes that while an entity is marked as
Static, it's properties will not change in any way visible to the user. You can basically think ofStaticentities as being part of "the map" or "the game world". Bevy doesn't setStaticon any entities by default; that is left to the end user. Static objects can be easily excluded from systems likepropagate_transformswithWithout<Static>.After the first frame in which a
Staticentity is view-visible, it is marked asCached. Render extraction systems can simply remove aentity_map.clear()and add aWithout<Cached>query bound to retain extractedStaticinformation.Cachedis removed automatically from entities that are notStatic, and can also be manually unset in the main world to cause a cache flush.StaticandCachedare tabled-backed. This means there is a reasonably large fixed cost to adding or removing these components. But this also means that entities with these components get kicked off into their own archetypes, and so have no query-iteration overhead (unlikeChanged<T>). This can lead to large performance gains in several schedules (but particularly in render extraction) when the vast majority of rendered objects areStatic, andStaticis only rarely added or removed.The current implementation is a prototype. I am still trying to identify other hot queries that could benefit from
Without<Cached>.I have profiled this against
many_cubesandmany_lights. Both show a significant potential for improvement over main, but I'd like to hold off on posting any of my results until this is more complete.Here are some potential issues:
render_mesh_instancesare never cleared.Cachedcontrols when they are overwritten, and only visible entities are accessed. The memory cost is minimal compared to the time cost of clearing out-of-view cached items.StaticandCachedstuff. I plan to add this but it may require tweakingpropagate_transforms.propagate_transformsneeds to visit every static node with children. Combining this approach with Parallelized transform propagation #11760 will significantly improve this issue.