`prepare_mesh_bind_groups` iterates over all meshes, even ones that are currently unused
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
This was discovered on 0.18.1, but has been tested on `main` and the issue persists. The issue is present on macOS, I haven't tested on other platforms at time of writing.
I'm working on a game that uses precalculated visibility, i.e. I know ahead of time the maximum set of potentially visible entities that need to be rendered is. For particularly heavy scenes, when they are first loaded they run very well, but the performance tanks after moving the camera around the whole map and back to the same position. In the worst case, the performance went to 240fps to 20fps in the same position, with the only change being that all the meshes in the level have been rendered once.
Using `tracey`, I tracked the issue [down to this line](https://github.com/bevyengine/bevy/blob/84be6ac40c88eb7c5ba0243e3d6902058225c6b6/crates/bevy_pbr/src/render/mesh.rs#L4066). At least, my best guess is that it's this line causing the issue.
When a mesh is rendered for the first time, it's extracted to the `RenderAssets` resource. However, if all instances of that mesh become invisible to all cameras via mechanisms like `Visibility` and `RenderLayers`, the mesh still gets processed as part of `prepare_mesh_bind_groups`. As a result, this system increases in time taken until the assets are removed from the main world's `AssetServer`. Since this system takes up a non-trivial percentage of the render world's CPU time even in perfect conditions, I believe that having some way to filter out unnecessary meshes would be a significant boost to render performance.
Contributor guide
Research direction
Start at crates/bevy_pbr/src/render/mesh.rs around prepare_mesh_bind_groups and the referenced line 4066. Reproduce the reported visibility scenario on main, profile the render world's CPU time as meshes become invisible, and trace how RenderAssets are processed. Done means unused meshes no longer cause the observed processing growth while visible meshes still render correctly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100