-
-
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
Race condition in assets loading #10688
Comments
I can repro on my machine.
I don't think this is true. From what I'm seeing in your app / my tests, whenever LoadState::Loaded is set, the asset is available. Ex: if I read the asset data from I think this is likely a rendering delay, not an asset system delay. Looks like your app operates under the assumption that it can spawn a scene, wait for the asset to load and create a camera/render on frame X, cleanup on frame X+1, and then restart the process. I'm guessing theres something preventing the spawned scene from rendering immediately on frame X. I do think this pattern should work in Bevy (ex: be able to easily and predictably know when a spawned scene is ready for render). Just want to make sure we're solving the right problem. |
One issue with the pattern you are using: If the goal is to know when a scene is "fully ready", you should be checking both. Alternatively, you can just listen for However even when adapted to use that event, it still doesn't always render. I have more confirmations of the theory in the previous post: I've constrained the example to only 4 items for easier debugging. In this case, the bench asset fails to load:
Note that nothing was rendered for the bench and a lot of entities were skipped for missing materials / material instances. Also note that the leaves on the bush didn't render for the same reason. |
Honestly no, it's was just my assumption. It worked on 0.11, and since asset system heavily changed I assumed that this could be the case.
Didn't know about it, will use it too. With checking
In my game asset could already be spawned (e.g. loaded), this is why I have to check it like this. So looks like the scene spawned partially? This is interesting. |
Yeah a combined state seems reasonable.
I'm pretty sure the scene is fully spawned, given that we are trying to render the things that aren't showing up (and skipping them because of missing GPU-side materials). I strongly suspect it would fully render if given a couple more frames. That being said, I still consider this a bug to be fixed (somehow). Easily determining when a scene will be fully rendered is important. |
Ok found the fix! It actually wasn't a bug in the renderer or the asset system. It was an issue with how the GLTF loader constructs its scenes. The dependencies were being added to the top level GLTF instead of to the Scene sub-assets, meaning the scenes were entering the LoadedWithDependencies state "immediately" because there were no dependencies. This is a reasonably straightforward fix. I have a hackey one put together to prove this works, but I'll come up with something a bit nicer. |
…10745) # Objective Fixes #10688 There were a number of issues at play: 1. The GLTF loader was not registering Scene dependencies properly. They were being registered at the root instead of on the scene assets. This made `LoadedWithDependencies` fire immediately on load. 2. Recursive labeled assets _inside_ of labeled assets were not being loaded. This only became relevant for scenes after fixing (1) because we now add labeled assets to the nested scene `LoadContext` instead of the root load context. I'm surprised nobody has hit this yet. I'm glad I caught it before somebody hit it. 3. Accessing "loaded with dependencies" state on the Asset Server is boilerplatey + error prone (because you need to manually query two states). ## Solution 1. In GltfLoader, use a nested LoadContext for scenes and load dependencies through that context. 2. In the `AssetServer`, load labeled assets recursively. 3. Added a simple `asset_server.is_loaded_with_dependencies(id)` I also added some docs to `LoadContext` to help prevent this problem in the future. --- ## Changelog - Added `AssetServer::is_loaded_with_dependencies` - Fixed GLTF Scene dependencies - Fixed nested labeled assets not being loaded --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
…10745) # Objective Fixes #10688 There were a number of issues at play: 1. The GLTF loader was not registering Scene dependencies properly. They were being registered at the root instead of on the scene assets. This made `LoadedWithDependencies` fire immediately on load. 2. Recursive labeled assets _inside_ of labeled assets were not being loaded. This only became relevant for scenes after fixing (1) because we now add labeled assets to the nested scene `LoadContext` instead of the root load context. I'm surprised nobody has hit this yet. I'm glad I caught it before somebody hit it. 3. Accessing "loaded with dependencies" state on the Asset Server is boilerplatey + error prone (because you need to manually query two states). ## Solution 1. In GltfLoader, use a nested LoadContext for scenes and load dependencies through that context. 2. In the `AssetServer`, load labeled assets recursively. 3. Added a simple `asset_server.is_loaded_with_dependencies(id)` I also added some docs to `LoadContext` to help prevent this problem in the future. --- ## Changelog - Added `AssetServer::is_loaded_with_dependencies` - Fixed GLTF Scene dependencies - Fixed nested labeled assets not being loaded --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Bevy version
0.12
What you did
My game have a plugin that generates preview images for buttons from 3D models. And I migrated from 0.11 to 0.12.
What went wrong
I noticed that my preview generation plugin sometimes generates empty images. I looked into it deeper and discovered that
AssetServer
sometimes returnsLoadState::Loaded
too early.Additional information
I managed to extract and simplify this logic into a minimal project that reproduces the issue: assets_render.zip
If you run it, you will see that some generated images are empty (sometimes happens on second run on my machine, but usually always happen):
If you disable
multi-threaded
feature inCargo.toml
, all images will be rendered correctly:The text was updated successfully, but these errors were encountered: