Dispatch and run compute shaders on bevy from App World .
Make an empty struct and implement ComputeShader
on it. the shader()
fn should point to your shader source code:
```rust
struct SimpleComputeShader;
impl ComputeShader for SimpleComputeShader { fn shader() -> ShaderRef { "shaders/simple.wgsl".into() } } ```
Add the plugin to your app:
```rust use bevy::prelude::*; use bevyappcompute::AppComputePlugin;
fn main() {
App::new()
.add_plugin(AppComputePlugin::
And then use the AppCompute<T>
resource to run compute shaders!
```rust use bevy::prelude::; use bevy_app_compute::prelude::;
fn mysystem(
appcompute: Res
// Create a new worker
let Some(mut worker) = app_compute.worker() else { return; };
// Add some uniforms and storages with default values
worker.add_uniform(0, "uni", 5f32);
worker.add_storage(0, "storage", vec![0f32; 8]);
// Create a buffer needed to get data back from the GPU
// It has to be linked to a storage.
worker.add_staging_buffer("staging", "storage", std::mem::size_of::<f32>() * 8);
// run the shader
worker.run((8, 1, 1));
// You can read data from your staging buffer now
let result = worker.get_data("staging");
let value: &[f32] = cast_slice(&result);
println!("value: {:?}", value);
} ```
You can run your compute shaders asynchronously to avoid loosing frame time.
```rust use bevy::prelude::; use bevy_app_compute::prelude::;
fn mysendersystem(
mut app_compute: ResMut
let Some(mut worker) = app_compute.worker() else { return; };
worker.add_storage(0, "storage", [0f32; 30]);
worker.add_staging_buffer("staging", "storage", std::mem::size_of::<f32>() * 30);
// queue your worker for later use
app_compute.queue(worker, (30, 1, 1));
}
fn myreceiversystem(
mut workerevents: EventReader
let result = worker.get_data("staging");
let value: &[f32] = cast_slice(&result);
println!("got {} items back!", value.len());
}
} ```
See examples