Crate bevy_hanabi

Crate bevy_hanabi 

Source
Expand description

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

The 🎆 Hanabi particle system is a GPU-based particle system integrated with the built-in Bevy renderer. It allows creating complex visual effects with millions of particles simulated in real time, by leveraging the power of compute shaders and offloading most of the work of particle simulating to the GPU.

The library supports the wasm target (WebAssembly) via the WebGPU renderer only. Compute shaders are not available via the legacy WebGL2 renderer. See Bevy’s own WebGL2 and WebGPU section of the examples README for more information on how to run Wasm builds with WebGPU.

§2D vs. 3D

🎆 Hanabi integrates both with the 2D and the 3D core pipelines of Bevy. The 2D pipeline integration is controlled by the 2d cargo feature, while the 3D pipeline integration is controlled by the 3d cargo feature. Both features are enabled by default for convenience. As an optimization, users can disable default features and re-enable only one of the two modes. At least one of the 2d or 3d features must be enabled.

# Example: enable only 3D integration
bevy_hanabi = { version = "0.15", default-features = false, features = ["3d"] }

§Example

Add the 🎆 Hanabi plugin to your app:

use bevy_hanabi::prelude::*;

App::default()
    .add_plugins(DefaultPlugins)
    .add_plugins(HanabiPlugin)
    .run();

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::ZERO);

    // 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 will stay
    // alive forever, and new particles can't be spawned instead.
    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
        32768,
        // 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,
        blend: ColorBlendMode::Overwrite,
        mask: ColorBlendMask::RGBA,
    });

    // Insert into the asset system
    let effect_asset = effects.add(effect);
}

Then add an instance of that effect to an entity by spawning a ParticleEffect component referencing the asset.

commands.spawn((
    ParticleEffect::new(effect_asset),
    Transform::from_translation(Vec3::Y),
));

§Workflow

Authoring and using a particle effect follows this workflow:

  1. Create an EffectAsset representing the definition of the particle effect. This asset is a proper Bevy Asset, expected to be authored in advance, serialized, and shipped with your application. Creating an EffectAsset at runtime while the application is running is also supported, though. In any case however, the asset doesn’t do anything by itself.
  2. At runtime, when the application is running, create an actual particle effect instance by spawning a ParticleEffect component. The component references the EffectAsset via its handle field. Multiple instances can reference the same asset at the same time, and some changes to the asset are reflected to its instances, although not all changes are supported. In general, avoid changing an EffectAsset while it’s in use by one or more ParticleEffect.
  3. If using properties, spawn an EffectProperties component on the same entity. Then update properties through that component at any time while the effect is active. This allows some moderate CPU-side control over the simulation and rendering of the effect, without having to destroy the effect and re-create a new one.
  4. If using textures, spawn an EffectMaterial component to define which texture is bound to which slot in the effect. An EffectAsset only defines “slots” of textures, not the actual assets bound to those slots. This way, you can reuse the same effect asset multiple times with different textures, like you’d do with a regular rendering mesh.
  5. For advanced VFX composed of multiple hierarchical effects, where two or more effects are connected to each other in a parent-child relationship, spawn an EffectParent on any child effect instance to specify its parent instance. See also the EmitSpawnEventModifier.

The EffectAsset is intended to be the serialized effect format, which authors can save to disk and ship with their application. At this time however serialization and deserialization is still a work in progress. In particular, serialization and deserialization of all modifiers is currently not supported on wasm target.

Re-exports§

pub use attributes::*;
pub use graph::*;
pub use modifier::*;
pub use properties::*;

Modules§

attributes
Effect attributes, like the position or velocity of a particle.
graph
Effect graph and language definition, including expressions.
modifier
Building blocks to create a visual effect.
prelude
properties
Effect properties.

Structs§

CompiledParticleEffect
Compiled data for a ParticleEffect.
DebugSettings
Debugging settings.
DefaultMesh
Default particle mesh, if not otherwise specified in EffectAsset::mesh.
EffectAsset
Asset describing a visual effect.
EffectMaterial
Material for an effect instance.
EffectParent
Component defining the parent effect of the current effect.
EffectSimulation
The effect simulation clock.
EffectSpawner
Runtime state machine for CPU particle spawning.
EffectVisibilityClass
The VisibilityClass used for all particle effects.
Gradient
A gradient curve made of keypoints and associated values.
GradientKey
A single key point for a Gradient.
HanabiPlugin
Plugin to add systems related to Hanabi.
LayoutFlags
Effect flags.
ParticleEffect
Particle-based visual effect instance.
PropertyValue
Value a user wants to assign to a property with EffectProperties::set() before the instance had a chance to inspect its underlying asset and check the asset’s defined properties.
Random
An RNG resource
ShaderCache
Cache of baked shaders variants.
SpawnerSettings
Settings for an EffectSpawner.
TextureLayout
Texture layout.
TextureSlot
Texture slot of a Module.

Enums§

AlphaMode
Alpha mode for rendering an effect.
CpuValue
A constant or random value evaluated on CPU.
EffectSystems
Labels for the Hanabi systems.
MotionIntegration
Type of motion integration applied to the particles of a system.
ShaderGenerateError
Error resulting from the generating of the WGSL shader code of an EffectAsset.
SimulationCondition
Simulation condition for an effect.
SimulationSpace
Simulation space for the particles of an effect.

Traits§

EffectSimulationTime
All methods for the Time<EffectSimulation> clock.
ToWgslString
Extension trait to convert an object to WGSL code.

Functions§

tick_spawners
Tick all the EffectSpawner components.