bevy icon indicating copy to clipboard operation
bevy copied to clipboard

AssetPack syntax sugar for static assets

Open ecoskey opened this issue 1 year ago • 3 comments

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 AssetPack trait and derive macro
  • Add AssetPackPlugin<T> to setup asset pack state
  • Add Pack<T> resource to wrap access to an AssetPack
  • Add GetPack<T> SystemParam so users don't have to pass in AssetServer themselves
  • Add asset_pack example and docs

ecoskey avatar Jun 11 '24 23:06 ecoskey

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.

github-actions[bot] avatar Jun 11 '24 23:06 github-actions[bot]

Instead of AssetPackPlugin, you could just provide a register_asset_pack fn.

brandon-reinhart avatar Jun 12 '24 03:06 brandon-reinhart

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 :)

ecoskey avatar Jul 13 '24 16:07 ecoskey

I haven't particularly encountered the pain that this is fixing yet, but my projects are not heavy on complex rendering or elaborate assets.

alice-i-cecile avatar Jul 14 '24 19:07 alice-i-cecile

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).

ecoskey avatar Jul 14 '24 21:07 ecoskey

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)

ecoskey avatar Aug 05 '24 04:08 ecoskey