-
-
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
Make sprites and text2d work with RenderLayers (add ComputedVisibility) #4007
Conversation
Please also check with the |
To avoid the memory allocations, you could store the hash set in a |
Some possible insights into what exactly makes it slower:
So it seems that building the hash set is not the problem (or at least a very small one), it's actually checking it when iterating the extracted_sprites. TL;DR: It's a 17% decline in performance with |
Did you try iterating the visible entities and getting them from the query and not using a |
Won't this mess up the z-ordering (sprites can be transparent)? I guess I could still try it for comparison. Or do you mean copy all the visible sprites into a new vec and then sort that? Also, what I'm currently doing is building a hashset (should bo O(n)?), and then checking whether an entity is in that hashset should be average constant time, right? EDIT: Also, in |
I would really love to get this merged, as I am using multiple camera with different |
Quick and dirty ComputedVisiblity support for sprites, text2d This is needed for RenderLayers to work properly Use a HashSet to speed up visibility checking Remove resolved todo Don't reallocate visible sprite entities map every frame
Quick and dirty ComputedVisiblity support for sprites, text2d This is needed for RenderLayers to work properly Use a HashSet to speed up visibility checking Remove resolved todo Don't reallocate visible sprite entities map every frame
Quick and dirty ComputedVisiblity support for sprites, text2d This is needed for RenderLayers to work properly Use a HashSet to speed up visibility checking Remove resolved todo Don't reallocate visible sprite entities map every frame
I would like to get this merged. #4745 makes it much easier to use multiple cameras, so probably more people will run into this |
This is needed for RenderLayers to work properly
456b5ce
to
759c292
Compare
Rebased to fix conflicts |
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.
If performance is an issue, I have a small suggestion on how to speed it up.
let extracted_sprites = &mut extracted_sprites.sprites; | ||
let image_bind_groups = &mut *image_bind_groups; | ||
|
||
visible_entities_map.clear(); |
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.
Consider using a FixedBitset
instead of a HashMap
here. A contains check using that should be faster than a HashSet
, it doesn't involve a O(capacity)
scan in the worst case and does not involve a hash on each lookup. Instead of storing the full entity, convert the u32
Entity ID into a usize
index, and use that to set and check the FixedBitset
.
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.
I agree that that suggestion should be an improvement to performance. I want to try to figure out if there is a way to restructure so that the set can be avoided.
@james7132 did you ever try using a fixed bit set for visible entities? I seem to remember that you did but I don’t remember.
Also, random thought that is not thought through and that may not be good but could be, is it worth storing a fixed bit set of views in which an entity is visible, per entity, instead of a fixed bit set of entities visible per-view? Maybe not as maybe the per-view set is small enough to stay in cache where the per-entity sets would be loaded in as part of iteration… I don’t know.
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.
VisibleEntities IMO shouldn't, though I haven't tried. It'd require an &Entities on the other end to resolve the Entity from the ID, which may or may not be desirable depending on the downstream use case.
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.
This will be a useful change if we can reduce/avoid the performance deficit.
events: Res<SpriteAssetEvents>, | ||
mut visible_entities_map: Local<HashSet<Entity>>, |
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.
This isn’t a map, it’s a set.
sprite_query: Query<(&Visibility, &Sprite, &GlobalTransform, &Handle<Image>)>, | ||
sprite_query: Query<( | ||
Entity, | ||
&Visibility, |
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.
ComputedVisibility needs to be used for extraction.
atlas_query: Query<( | ||
Entity, | ||
&Visibility, |
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.
ComputedVisibility needs to be used for extraction here too.
let extracted_sprites = &mut extracted_sprites.sprites; | ||
let image_bind_groups = &mut *image_bind_groups; | ||
|
||
visible_entities_map.clear(); |
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.
I agree that that suggestion should be an improvement to performance. I want to try to figure out if there is a way to restructure so that the set can be avoided.
@james7132 did you ever try using a fixed bit set for visible entities? I seem to remember that you did but I don’t remember.
Also, random thought that is not thought through and that may not be good but could be, is it worth storing a fixed bit set of views in which an entity is visible, per entity, instead of a fixed bit set of entities visible per-view? Maybe not as maybe the per-view set is small enough to stay in cache where the per-entity sets would be loaded in as part of iteration… I don’t know.
In addition to |
Given that RenderLayers-like functionality is pretty important for things like "camera driven rendering", I think we might need to just eat this perf cost. Added this to the 0.8 milestone as I think its worth making a call on "2d visibility controls" as part of the "camera driven rendering" story. |
This was last updated 24 days ago but #4489 was merged 12 days ago and will impact real world performance. Also, I have ideas for improving sprite rendering performance further so we can probably take the hit. |
I've made a version #5114 with a different tradeoff between straight logic and performance. Any opinions are much appreciated. |
Has this been superseeded by #5310? |
Yes, |
Objective
Solution
Maybe there are more efficient ways of doing this than recreating hashmaps all the time?
Anyways, I didn't see any drop in performance when running the
bevymark
example, so perhaps it's ok.EDIT: It's a ~17% decline in performance with many_sprites, but no change in bevymark. bevymark is perhaps a bit contrived? Isn't it better to be correct than performant? Most of the performance hit seems to be caused by sampling the hashmap.