A lightweight, cross-platform Bevy plugin that provides a KTX2 Basis Universal texture loader.
Although Bevy's ImageLoader has built-in support for Basis Universal textures via the basis-universal-rs crate, it has some limitations:
- It uses a very old version of Basis Universal.
- No support for UASTC HDR yet, either ASTC, XUASTC which are added in basis universal v2.0.
- No support for Web. Bevy can't be compiled to
wasm32-unknown-emscriptenandbasis-universal-rscan't be compiled towasm32-unknown-unknown. - It compiles both the encoder and transcoder and includes transcoding formats not supported by wgpu, which increases binary size.
This plugin adds a loader for Basis Universal KTX2 textures with support for all formats supported by basis universal v2.0 (ETC1S, UASTC, ASTC, XUASTC), and web support through JavaScript glue to call Basis Universal C++ library compiled with Emscripten which includes only the transcoder and necessary transcoding formats.
Note: This doesn't include BasisU encoder. To encode textures to .ktx2, use the command line tool in Basis Universal repo.
Web demo: https://beicause.github.io/bevy_basisu_loader/
- Add the Cargo dependency:
bevy_basisu_loader = "0.3"- Add
BasisuLoaderPlugin:
use bevy_basisu_loader::BasisuLoaderPlugin;
pub fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(BasisuLoaderPlugin);
}- Load ktx2 basis universal textures. Supports
D2,D2ArrayandCubetexture types. Zstd supercompression is supported. Note: Only supports.ktx2format,.basisformat is not supported.
let image_handle = asset_server.load("gl_skybox_etc1s_cubemap_mips_12.basisu.ktx2");.basisu.ktx2 to load it with this BasisuLoader, otherwise bevy will load .ktx2 files with the builtin ImageLoader.
To run on web, this repo uses a solution:
The crates/basisu_sys/ contains a high level wrapper of the basis universal C++ library.
For native platforms, it just builds and statically links the C++ library.
For web, it contains a tool to build basisu vendor using Emscripten and produce js and wasm files. The basisu wrapper is designed so that it does not need to share memory with main Wasm module, instead its memory is copied from/into main Wasm module through javascript. When building this plugin targeting wasm32-unknown-unknown, the basisu vendor js and wasm files will be embedded into binary and is called through wasm-bindgen and js-sys.
TLDR: Just build your bevy application to wasm32-unknown-unknown normally.
The prebuilt wasm in crates/basisu_sys/wasm is automatically embedded in binary when building. It was prebuilt through CI with:
cargo r -p bevy_basisu_loader_sys --bin build-wasm-cli --features build-wasm-cli -- --emcc-flags="-Os -msimd128 -flto=full -sEVAL_CTORS" --wasm-opt-flags="-Os --enable-simd --enable-bulk-memory-opt --enable-nontrapping-float-to-int"bevy |
bevy_basisu_loader |
basis_universal |
|---|---|---|
| 0.18 | 0.3, 0.4 | v2_0_2 |
| 0.17 | 0.1, 0.2 | v1_60_snapshot |
Except where noted (below and/or in individual files), all code in this repository is dual-licensed under either:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.