AssetPack syntax sugar for static assets
Objective
Currently there's not a ton of boilerplate for loading assets, either using embedded_asset! or not. But this can still add up, and does especially in rendering code.
Solution
- Add AssetPack trait and derive macro to wrap the pattern of "initialize some resources, potentially through embedded_asset!, and lazy load them when required"
#[derive(AssetPack)]
struct BloomShaders {
#[embedded("upscale.wgsl")] //lazy-loads upscale.wgsl as an embedded asset
upscale_shader: Handle<Shader>,
#[load("downscale.wgsl")] //lazy-loads downscale.wgsl from the default asset source
downscale_shader: Handle<Shader>,
}
Limitations
Currently, all assets are loaded at once in Pack<T>::get() and never unloaded. This fits the need of rendering (and I assume other cases as well), where each shader is needed every frame and each pack is accessed (usually) all at once. Loading assets separately and unloading assets when unused would require a function-like proc-macro to be able to rewrite each struct field. For this PR I decided to continue with the simpler implementation.
Testing
I did some quick manual testing to make sure the macro worked as expected. Frankly, I'm not super familiar with macro testing or style for error reporting. Please let me know how to improve this!
Changelog
- Add
AssetPacktrait and derive macro - Add
AssetPackPlugin<T>to setup asset pack state - Add
Pack<T>resource to wrap access to anAssetPack - Add
GetPack<T>SystemParam so users don't have to pass inAssetServerthemselves - Add
asset_packexample and docs
The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.
Instead of AssetPackPlugin, you could just provide a register_asset_pack fn.
I tried running the example but got...
Apparently this is due to the weird workspace setup examples use. I just added a new top-level attribute to override the workspace root for embedded_asset!, so the example should be fixed :)
I haven't particularly encountered the pain that this is fixing yet, but my projects are not heavy on complex rendering or elaborate assets.
It's not an unbearable level of pain even, just the simple but pretty repetitive boilerplate of loading a fixed set of static assets into a resource handle and accessing them later. In terms of more tangible benefits, we lazy load assets (although not individually) and only refer to the path of the asset once rather than twice (potential for mismatch).
Decided to spin this off as a separate crate since there's not much attention here and any in-engine use seems far off (rendering refactor)