-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Optimize ShaderDefs updates #1046
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
Conversation
- change ShaderDefIterator to iterate every ShaderDef defined or not - remove clear system, and only update on change
query | ||
.iter_mut() | ||
// (Handle<T>, _) -> (&T, _) | ||
.filter_map(|(h, p)| assets.get(h).map(|a| (a, p))) |
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 expect this to behave incorrectly when an asset isn't loaded yet. Ex:
- begin loading a "shader def" asset and assign its handle to a component
- this system runs. the entity with the handle shows up in the query iteration because the handle was changed
- it gets filtered out because the asset isn't loaded yet
- later, when the asset finishes loading, this system doesn't run on the entity we skipped, because the Changed flag is no longer set.
Good call! This is definitely something we should do incrementally. Just one hangup (see comment above) |
Hmm, this doesn't happen in practice with StandardMaterial or ColorMaterial. You'd have to be deserializing ShaderDefs off disk or something? So I should track empty handles and wait for asset creation events later? |
Yeah currently its not a huge problem because StandardMaterial and ColorMaterial are generally created "immediately". But as soon as we start loading materials from disk, we'll hit this problem (ex: its probably already a problem when using StandardMaterial handles from a still-loading gltf file) Your suggested fix is how we should do it. We also need to account for "asset change events". Because the value of the asset could change after loading it. I think using the general approach we use for meshes is probably the right call: bevy/crates/bevy_render/src/mesh/mesh.rs Line 334 in 9239621
Another Problem
I'm now realizing that this breaks down when the asset "changes". Doing this "incrementally" is actually pretty hard. We would need to:
This is do-able, but not with the current design. Rather than merge them all into a single ShaderDefs, maybe it should be a key->value mapping that gets merged when we actually compile the shader. That way we could "replace" the shader defs for a specific context without knowing about the global context (or needing to know the past values for a given context). |
I tried getting it to happen with the gltf example. The stock impls of ShaderDefs don't care if the sub-assets are loaded, only that the Option/bool is set. I can make a test case where it happens. So the key is the asset handle? And log warnings if there are collisions when merged? |
Yeah the key should probably be HandleUntyped so that we can support multiple handle types. |
I think collisions shouldn't be a problem. Can you see that producing undesirable behavior? |
@cart, this works as-is, minus some cleanup (mainly reverting the macro changes). I'm wondering what you think of not tracking entities <-> handles like It seems like there's a case here for a nicer abstraction for systems that deal with changing assets/handles. I see this pattern appears in a few places, but I haven't looked at all of them. |
Sorry for the delay. Diving back in now! |
{ | ||
query | ||
.iter_mut() | ||
.map(|(s, p)| (s, (T::TYPE_UUID).into(), p)) |
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.
Can we use the TypeId here instead of TypeUuid? So far we aren't requiring TypeUuid on components and we use TypeId as the unique identifier everywhere else.
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.
(Assets do require TypeUuid though)
Yeah I think this approach works great. Good call!
We should use TypeId here for now (see comment above)
Agreed. If we can find a better pattern I'm definitely sold! |
In general this approach looks good to me. Lets solve the FIX items, rebase / resolve conflicts, and transition out of draft mode! |
This still seems like a useful change - it seems that we still clear all the shader defs each frame (!) on However, I that this will get integrated into the upcoming render rework; if you don't want to continue pushing this forward, feel free to close it @yrns. I suspect rebasing this PR will not be useful at the moment, as the render rework is in flight - we can check back in once that lands to check the relevance of these changes then. |
Related to #63.