Home

Awesome

Rust WGPU hot-reload

https://github.com/Azkellas/rust_wgpu_hot_reload/assets/29731210/49643bd5-b56c-460e-940f-13d498e1533e

<details> <summary>Demo Boids</summary> https://github.com/Azkellas/rust_wgpu_hot_reload/assets/29731210/b3befb4d-6ef5-437e-a737-b99d32dbaa65 </details> <details> <summary>Demo Raymarching</summary> https://github.com/Azkellas/rust_wgpu_hot_reload/assets/29731210/592edece-d19e-48a1-9bab-e0e711511992 </details>

Hot reload both shaders and rust code while developing a WGPU application with egui integration.

Package a single binary/wasm for native and web targets.


Features


Running the project

To have both shader and rust hot reload, run:

Alternatively use cargo runcc -c runcc.yml to run both commands at the same time. (requires cargo-runcc)

You can also run cargo run if you only care about shader hot reloading.

cargo run --release as usual to build a single executable for your native target. For wasm builds, see below.


Building for the web

This project targets webgpu first, and defaults to webgl when not available.

# In charge of building and hosting a webserver. Should expose to localhost:8000
cargo run-wasm [--release] [--features ...]

Wgsl preprocessing

This project contains a small homemade preprocessor for wgsl files. It currently allows to include other files by using #import "path/to/file.wgsl" in your shader files.

This syntax follows the bevy preprocessor syntax, which is roughly supported by wgsl-analyzer.


Using the template

The project comes with a PipelineFuncs trait. Hopefully it should be enough for your needs. You just need to replace the current implementation with yours in lib/lib.rs: demo_pipelines::demo::Pipeline as CurrentPipeline;.


Project architecture

The project is divided in two crates: lib and src.

src should only contain the minimal code necessary to start the application and the windowing system, allowing a maximum of code to be hot-reloaded in lib which is built as a dynamic library and reloaded at runtime whenever changes are saved.

Entry point functions should be written in lib/src/lib.rs, be public and have the #[no_mangle] attribute to be hot-reloadable. Note that they cannot be generic. Example:

#[no_mangle]
pub fn get_pipeline_name(pipeline: &CurrentPipeline) -> String {
    pipeline.get_name().to_owned()
}

Then each use of the lib in src should be done via the module hot_lib::library_bridge that makes the bridge between the binary and the dynamic library.

See hot-lib-reloader-rs for more information about hot reloading Rust code and its limitations.


Troubleshooting


References: