bevy_app_compute-0.10.0 has been yanked.
Bevy App Compute

Dispatch and run compute shaders on bevy from App World .
Usage
Setup
Make an empty struct and implement ComputeShader
on it. the shader()
fn should point to your shader source code:
struct SimpleComputeShader;
impl ComputeShader for SimpleComputeShader {
fn shader() -> ShaderRef {
"shaders/simple.wgsl".into()
}
}
Add the plugin to your app:
use bevy::prelude::*;
use bevy_app_compute::AppComputePlugin;
fn main() {
App::new()
.add_plugin(AppComputePlugin::<SimpleComputeShader>::default());
}
And then use the AppCompute<T>
resource to run compute shaders!
use bevy::prelude::*;
use bevy_app_compute::prelude::*;
fn my_system(
app_compute: Res<AppCompute<SimpleComputeShader>>,
) {
let Some(mut worker) = app_compute.worker() else { return; };
worker.add_uniform(0, "uni", 5f32);
worker.add_storage(0, "storage", vec![0f32; 8]);
worker.add_staging_buffer("staging", "storage", std::mem::size_of::<f32>() * 8);
worker.run((8, 1, 1));
let result = worker.get_data("staging");
let value: &[f32] = cast_slice(&result);
println!("value: {:?}", value);
}
Asynchronous computation
You can run your compute shaders asynchronously to avoid loosing frame time.
use bevy::prelude::*;
use bevy_app_compute::prelude::*;
fn my_sender_system(
mut app_compute: ResMut<AppCompute<MyComputeShader>>
){
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);
app_compute.queue(worker, (30, 1, 1));
}
fn my_receiver_system(
mut worker_events: EventReader<WorkerEvent<MyComputeShader>>
) {
for ev in &mut worker_events.iter() {
let worker = &ev.worker;
let result = worker.get_data("staging");
let value: &[f32] = cast_slice(&result);
println!("got {} items back!", value.len());
}
}
Examples
See examples