-
-
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
Instanced line rendering for gizmos based on bevy_polyline
#8427
Instanced line rendering for gizmos based on bevy_polyline
#8427
Conversation
Co-authored-by: Jonas Matser <github@jonasmatser.nl> Co-authored-by: Aevyrie <aevyrie@gmail.com> Co-authored-by: Nicola Papale <nico@nicopap.ch>
IIRC, you're going to want to batch lines to get really good performance. You could probably aggregate all polylines during extract, and shove them into a single GPU uniform, where each set of vertices and colors are separated by a NaN, if you aren't doing this already. This would result in a single draw call for all polylines. It's also possible |
I should have clarified that bevy_gizmos is currently exclusively an immediate mode API.
I assumed above that this number is referring to static polylines. Is that right?
I learned the NaN trick from @IceSentry iirc, wouldn't be surprised if they got it from you :) All lines are split across just 2 batches. One for the NaN separated linestrip topology and one for linelist topology (Used only for single segment lines)
I wonder how much this might affect the performance of this implementation. I would like to keep the fancy color gradients q: |
Sorry, I didn't see that when I did a brief review of the changes. It's pretty awesome you're already doing this. 🙂
Yeah, it's a nice feature to have. You might have luck by treating it like mesh indices, and only storing colors as a list of indices into the list of colors. My guess is for most cases, this would significantly cut down on the amount of data that needs to be yeeted (yoten?) over to the GPU. You would be reducing memory use for color from 16 bytes ( Alternatively, you could keep the same approach as now, but use run length encoding to losslessly compress color information for polylines that use a single color. Another upside of that is it would allow you to easily add per-vertex line width and depth bias without blowing up memory usage in most cases. Anyway, these are obviously some potential optimizations for a future day. This PR is definitely a nice addition. |
No need to apologize :) Thanks for all the pointers!
It's good that you mention this. I was planning to enable more granular control over these settings in a future PR |
This PR is pretty big, is there anything that could be done in a follow up PR in order to keep this one a bit smaller?
Yep 😉 |
This is pretty much the minimal change required to do this line rendering technique. I already stripped down the code a quite a bit compared to bevy_polyline. Especially considering this includes both a 3d and a 2d pipeline. |
# Objective Compute the `vertex_count` for indexed meshes as well as non-indexed meshes. I will need this in a future PR based on #8427 that adds a gizmo component that draws the normals of a mesh when attached to an entity ([branch](tim-blackbird/bevy@instanced-line-rendering...devil-ira:bevy:instanced-line-rendering-normals)). <details><summary>Example image</summary> <p> ![image](https://user-images.githubusercontent.com/29694403/233789526-cb5feb47-0aa7-4e69-90a2-e31ec24aadff.png) </p> </details> ## Solution Move `vertex_count` field from `GpuBufferInfo::NonIndexed` to `GpuMesh` ## Migration Guide `vertex_count` is now stored directly on `GpuMesh` instead of `GpuBufferInfo::NonIndexed`.
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.
LGTM. You say it's a perf upgrade compared to LineList? That's surprising, but good for us, because that would be amazing to have size (even if joints are still an open question). I'd just like to avoid some magic numbers.
struct LineGizmoUniform { | ||
line_width: f32, | ||
depth_bias: f32, | ||
/// WebGL2 structs must be 16 byte aligned. | ||
#[cfg(feature = "webgl")] | ||
_padding: bevy_math::Vec2, | ||
} |
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.
So only a global line_width
and depth_bias
is possible? Given you only upload two instances.
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.
Currently, yes. I'll look into more granular configuration in a future PR.
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
This looks great, the performance increase is a significant one |
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.
LGTM, there's a couple of things that could be improved in the future, but it's already in a really nice state for 0.11
Merging for you: y'all have carefully considered this and have more than enough expertise between you. The code and changes look good from my end too. |
Dang merge failed |
# Objective Gizmos are intended to draw over everything but for some reason I set the sort key to `0` during #8427 :v I didn't catch this mistake because it still draws over sprites with a Z translation of `0`. ## Solution Set the sort key to `f32::INFINITY`.
# Objective Gizmos are intended to draw over everything but for some reason I set the sort key to `0` during #8427 :v I didn't catch this mistake because it still draws over sprites with a Z translation of `0`. ## Solution Set the sort key to `f32::INFINITY`.
Objective
Adopt code from bevy_polyline for gizmo line-rendering.
This adds configurable width and perspective rendering for the lines.
Many thanks to @mtsr for the initial work on bevy_polyline. Thanks to @aevyrie for maintaining it, @nicopap for adding the depth_bias feature and the other contributors for squashing bugs and keeping bevy_polyline up-to-date.
Before
After - with line perspective
Line perspective is not on by default because with perspective there is no default line width that works for every scene.
After - without line perspective
Somewhat unexpectedly, the performance is improved with this PR.
At 200,000 lines in many_gizmos I get ~110 FPS on main and ~200 FPS with this PR.
I'm guessing this is a CPU side difference as I would expect the rendering technique to be more expensive on the GPU to some extent, but I am not entirely sure.