🎆 Bevy Hanabi

🎆 Hanabi — a GPU particle system for the Bevy game engine.

Overview
The Hanabi particle system is a modern GPU-based particle system for the Bevy game engine. It focuses on scale to produce stunning visual effects (VFX) in real time, offloading most of the work to the GPU, with minimal CPU intervention. The design is inspired by modern particle systems found in other industry-leading game engines.
🚧 This project is under heavy development, and is currently lacking both features and performance / usability polish. However, for moderate-size effects, it can already be used in your project. Feedback and contributions on both design and features are very much welcome.
🎆 Hanabi makes heavy use of compute shaders to offload work to the GPU in a performant way. Support for compute shaders on the wasm target (WebAssembly) is available as of v0.13 (Bevy 0.14), and only through WebGPU. See the WebAssembly support documentation for details.
Usage
The 🎆 Bevy Hanabi plugin is compatible with Bevy versions >= 0.6; see Compatible Bevy versions.
Add the dependency
Add the bevy_hanabi dependency to Cargo.toml:
[dependencies]
bevy_hanabi = "0.20"
See also Features below for the list of supported features.
System setup
Add the HanabiPlugin to your app:
use bevy_hanabi::prelude::*;
App::default()
.add_plugins(DefaultPlugins)
.add_plugins(HanabiPlugin)
.run();
Create an effect asset
Create an EffectAsset describing a visual effect:
fn setup(mut effects: ResMut<Assets<EffectAsset>>) {
// Define a color gradient from red to transparent black
let mut gradient = Gradient::new();
gradient.add_key(0.0, Vec4::new(1., 0., 0., 1.));
gradient.add_key(1.0, Vec4::splat(0.));
// Create a new expression module
let mut module = Module::default();
// On spawn, randomly initialize the position of the particle
// to be over the surface of a sphere of radius 2 units.
let init_pos = SetPositionSphereModifier {
center: module.lit(Vec3::ZERO),
radius: module.lit(2.),
dimension: ShapeDimension::Surface,
};
// Also initialize a radial initial velocity to 6 units/sec
// away from the (same) sphere center.
let init_vel = SetVelocitySphereModifier {
center: module.lit(Vec3::ZERO),
speed: module.lit(6.),
};
// Initialize the total lifetime of the particle, that is
// the time for which it's simulated and rendered. This modifier
// is almost always required, otherwise the particles won't show.
let lifetime = module.lit(10.); // literal value "10.0"
let init_lifetime = SetAttributeModifier::new(
Attribute::LIFETIME, lifetime);
// Every frame, add a gravity-like acceleration downward
let accel = module.lit(Vec3::new(0., -3., 0.));
let update_accel = AccelModifier::new(accel);
// Create the effect asset
let effect = EffectAsset::new(
// Maximum number of particles alive at a time
1024,
// Spawn at a rate of 5 particles per second
SpawnerSettings::rate(5.0.into()),
// Move the expression module into the asset
module
)
.with_name("MyEffect")
.init(init_pos)
.init(init_vel)
.init(init_lifetime)
.update(update_accel)
// Render the particles with a color gradient over their
// lifetime. This maps the gradient key 0 to the particle spawn
// time, and the gradient key 1 to the particle death (10s).
.render(ColorOverLifetimeModifier { gradient, ..default() });
// Insert into the asset system
let effect_handle = effects.add(effect);
}
Spawn a particle effect
Use a ParticleEffect to create an effect instance from an existing asset.
commands.spawn((
ParticleEffect::new(effect_handle),
Transform::from_translation(Vec3::Y),
));
Examples
See the examples/ folder.
All examples run from one executable: cargo run --example demo opens an interactive menu, and cargo run --example demo -- --demo firework directly selects a demo to open. On WebAssembly, build with build_examples_wasm.sh (or .bat) and serve examples/wasm/; the same interactive menu lets you choose a demo in the browser.
The source-generated effect files under examples/effects/ can be regenerated with cargo run --example demo -- --write-effects and checked without modifying them with cargo run --example demo -- --check-effects. This shows how effects are serialized and deserialized.
Note for Linux users: The examples build with the bevy/x11 feature by default to enable support for the X11 display server. If you want to use the Wayland display server instead, add the bevy/wayland feature.
Feature List
This list contains the major fixed features provided by 🎆 Hanabi. Beyond that, with the power of the Expressions API, visual effect authors can further customize their effects by assigning individual particle attributes (position, color, etc.).
- Spawn
- Initialize
- Update
- Render
- Debug
Features
🎆 Bevy Hanabi supports the following cargo features:
| Feature |
Default |
Description |
2d |
✔ |
Enable rendering through 2D cameras (Camera2d) |
3d |
✔ |
Enable rendering through 3D cameras (Camera3d) |
For optimization purpose, users of a single type of camera can disable the other type by skipping default features in their Cargo.toml. For example to use only the 3D mode:
bevy_hanabi = { version = "0.20", default-features = false, features = [ "3d" ] }
Compatible Bevy versions
The main branch is compatible with the latest Bevy release.
Compatibility of bevy_hanabi versions:
bevy_hanabi |
bevy |
0.20 |
0.20 |
0.19 |
0.19 |
0.18 |
0.18 |
0.17 |
0.17 |
0.16 |
0.16 |
0.14-0.15 |
0.15 |
0.12-0.13 |
0.14 |
0.10-0.11 |
0.13 |
0.8-0.9 |
0.12 |
0.7 |
0.11 |
0.6 |
0.10 |
0.5 |
0.9 |
0.3-0.4 |
0.8 |
0.2 |
0.7 |
0.1 |
0.6 |
License
🎆 Hanabi is dual-licensed under either:
at your option.
SPDX-License-Identifier: MIT OR Apache-2.0
评论