2D particle system with custom material traits. Works well in wasm webgl2 and mobile

Overview

Bevy Enoki

License: MIT or Apache 2.0 Crate

Enoki - A 2D particle system for the Bevy game engine.

animation

Overview

The Enoki particle system is a CPU calculate particle system, that uses GPU Instancing and works well with wasm. It provides a material trait that lets you easily implement your own fragment shader for all your VFX needs. Additionally, spawner configuration are provided via ron files, which can be hot reloaded.

The default material allows not only for custom textures, but also sprite sheet animations over the particle lifetime.

🚧 This Plugin just released and is still under heavy development. The particle behavior is very basic and performance could be better. Expect rapid change. Planned is orbital velocity, attractors and simple physics. When 2d is fleshed out and the best it can be, 3d might happen.

Compatibility

bevy bevy_enoki
0.14 0.2.1
0.13 0.1

Editor

Check out the new Web based particle editor at Enoki Particle Editor. Easily adjust your effects by importing and exporting the Ron configuration.

Examples

cargo run --example material
cargo run --example sprites
cargo run --example dynamic

Usage

Add the bevy_enoki dependency to your Cargo.toml

bevy_enoki = "0.1"

Add the EnokiPlugin to your app

App::new()
    .add_plugins(DefaultPlugins)
    .add_plugins(EnokiPlugin)
    .run()

Create your first particle spawner. Here is a default effect config

use bevy_enoki::prelude::*;

fn setup(
    mut cmd : Commands,
    mut materials: ResMut<Assets<SpriteParticle2dMaterial>>,
    server : Res<AssetServer>,
){
    cmd.spawn(Camera2dBundle::default());

    //spawning quads
    cmd.spawn((
        ParticleSpawnerBundle {
            // load the effect configuration from a ron file
            effect: server.load("fire.particle.ron"),
            // the default materiel is just a flat white color
            // that gets multiplied by any color curve inside the
            // effect definition of the `ron` file.
            material: DEFAULT_MATERIAL,
            ..default()
        },
    ));

    // if you want to add a texture, use the inbuild `ColorParticle2dMaterial`
    let texture_material = materials.add(
        // hframes and vframes define how the sprite sheet is divided for animations,
        // if you just want to bind a single texture, leave both at 1.
        SpriteParticle2dMaterial::new(server.load("particle.png"), 6, 1),
    );

    cmd.spawn((
        ParticleSpawnerBundle {
            effect: server.load("fire.particle.ron"),
            material: texture_material,
            ..default()
        },
    ));
}

Create a custom Material

Just like any other Bevy material, you can define your own fragment shader.

#[derive(AsBindGroup, Asset, TypePath, Clone, Default)]
pub struct FireParticleMaterial {
    #[texture(0)]
    #[sampler(1)]
    texture: Handle<Image>,
}

impl Particle2dMaterial for FireParticleMaterial {
    fn fragment_shader() -> bevy::render::render_resource::ShaderRef {
        "custom_material.wgsl".into()
    }
}

fn setup(){
    App::default()
        .add_plugins(DefaultPlugins)
        .add_plugins(EnokiPlugin)
        .add_plugins(Particle2dMaterialPlugin::<FireParticleMaterial>::default())
        .run()
}

Now create the Shader

//assets/custom_material.wgsl
#import bevy_enoki::particle_vertex_out::{ VertexOutput }

@group(1) @binding(0) var texture: texture_2d<f32>;
@group(1) @binding(1) var texture_sampler: sampler;


@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var out = in.color
    // go wild
    return out;
}

That's it, now add the Material to your Spawner! These are the values provided by the vertex shader:

struct VertexOutput {
  @builtin(position) clip_position: vec4<f32>,
  @location(0) @interpolate(flat) color: vec4<f32>,
  @location(1) uv : vec2<f32>,
  @location(2) lifetime_frac : f32,
  @location(3) lifetime_total : f32,
};

The Effect Asset

Here is a default ron config

#[derive(Deserialize, Default, Clone, Debug)]
pub enum EmissionShape {
    #[default]
    Point,
    Circle(f32),
}

#[derive(Asset, TypePath, Default, Deserialize, Clone, Debug)]
pub struct Particle2dEffect {
    pub spawn_rate: f32,
    pub spawn_amount: u32,
    pub emission_shape: EmissionShape,
    pub lifetime: Rval<f32>,
    pub linear_speed: Option<Rval<f32>>,
    pub linear_acceleration: Option<Rval<f32>>,
    pub direction: Option<Rval<Vec2>>,
    pub angular_speed: Option<Rval<f32>>,
    pub angular_acceleration: Option<Rval<f32>>,
    pub scale: Option<Rval<f32>>,
    pub color: Option<LinearRgba>,
    pub gravity_direction: Option<Rval<Vec2>>,
    pub gravity_speed: Option<Rval<f32>>,
    pub linear_damp: Option<Rval<f32>>,
    pub angular_damp: Option<Rval<f32>>,
    pub scale_curve: Option<Curve<f32>>,
    pub color_curve: Option<Curve<LinearRgba>>,
}

This how you create a Curve. Currently, Supports LinearRgba and f32. RVal stands for any Value with a randomness property between 0 - 1.

let curve = Curve::new()
    .with_point(LinearRgba::RED, 0.0, None)
    .with_point(LinearRgba::BLUE, 1.0, Some(bevy_enoki::prelude::EaseFunction::SineInOut));

// max 1.0, randomness of 0.1 (0.9 - 1.1)
let rval = Rval::new(1.0, 0.1);
You might also like...
Gun port in rust & wasm

gun-rs-wasm Rust & WASM port of Gun. For a non-wasm version, check out gun-rs Example (source) Use npm install rusty-gun import { Node as Gun } from "

Install `wasm-pack` by downloading the executable

wasm-pack-action Install wasm-pack by downloading the executable (much faster than cargo install wasm-pack, seconds vs minutes). Usage - uses: jetli/w

`wasm-snip` replaces a WebAssembly function's body with an `unreachable`

wasm-snip wasm-snip replaces a Wasm function's body with an unreachable instruction. API Docs | Contributing | Chat Built with πŸ¦€ πŸ•Έ by The Rust and W

gc-sections for wasm

wasm-gc Note: you probably don't need to use this project. This project is no longer necessary to run by hand, nor do you need the wasm-gc executable

List the symbols within a wasm file

wasm-nm List the symbols within a wasm file. Library Executable License Contributing Executable To install the wasm-nm executable, run $ cargo install

Just a little game I made in a day to try out the WASM-4 fantasy console.

Dodgeball This is just a little game I made in a day to try out the WASM-4 fantasy console. Play it here. The palette is SODA-CAP by Cappuchi. License

WebAssembly (Wasm) interpreter.

Continuous Integration Test Coverage Documentation Crates.io wasmi- WebAssembly (Wasm) Interpreter wasmi was conceived as a component of parity-ethere

πŸ“ A template for creating WASM + Typescript + Rust workflow libraries.
πŸ“ A template for creating WASM + Typescript + Rust workflow libraries.

Create Rust + TypeScript libraries with ease! PR'S WELCOMED! ✨ Inspiration I wanted to create a WebAssembly/Rust library with additional JS features,

A self-guided learning project that includes Rust + Wasm together
A self-guided learning project that includes Rust + Wasm together

A self-guided learning project that includes Rust + Wasm together. Who knows, maybe Typescript and React joins too..

Comments
  • DEFAULT_MATERIAL does not apply color anymore

    DEFAULT_MATERIAL does not apply color anymore

    The latest release stops coloring particles over time like the older version did. if you change the material example:

    Screenshot 2024-07-07 at 08 19 07

    to use DEFAULT_MATERIAL and compare the previous release visual: Screenshot 2024-07-07 at 08 13 26

    with the current: Screenshot 2024-07-07 at 08 17 32

    you see the missing blue coloring.

    opened by extrawurst 0
Owner
Lorenz
Game-dev, full-stack web and everything fun
Lorenz
Facilitating high-level interactions between Wasm modules and JavaScript

wasm-bindgen Facilitating high-level interactions between Wasm modules and JavaScript. Guide | API Docs | Contributing | Chat Built with ?? ?? by The

Rust and WebAssembly 5.9k Jan 8, 2023
Instrument and transform wasm modules.

wasm-instrument A Rust library containing a collection of wasm module instrumentations and transformations mainly useful for wasm based block chains a

Parity Technologies 31 Dec 16, 2022
Parametric surfaces drawn using the Rust + WASM toolchain with WebGL, React, and TypeScript.

Parametric Surfaces in the Browser My.Movie.3.mp4 Wanted to experiment with WebGL using the Rust + WASM toolchain, with React and TypeScript to glue e

Benji Nguyen 45 Oct 21, 2022
Rust implementation of the Mina protocol, targeting Wasm and ARM architectures.

Mina-rs An implementation of Mina protocol in Rust, with focus on web and Wasm compatibility ** As you can probably tell this is a WIP! Don't use for

ChainSafe 157 Dec 12, 2022
WASM bindings for React - enables you to write and use React components in Rust

This library enables you to write and use React components in Rust, which then can be exported to JS to be reused or rendered.

Yichuan Shen 55 Dec 24, 2022
TSS of GG18 by WASM, for Confidential Transaction Generation and Signing

TSS WASM portable lightweight client application for threshold ECDSA (based on GG18), built on&for multi-party-ecdsa : Wasm HW friendly Dev yarn build

Eigen Labs 24 Dec 28, 2022
Lunatic based webserver embedding WASM. Supports scaling down to zero and up to infinity.

Frenezulo A WASM-embedding webserver build on top of submillisecond and lunatic. Build to serve as an entry point for microservices compiled to WASM.

Kai Jellinghaus 13 Oct 23, 2022
Spine runtime for Rust (and wasm!) transpiled from the official C Runtime.

rusty_spine Spine runtime for Rust (and wasm!) transpiled from the official C Runtime. Supports Spine 4.1. [dependencies] rusty_spine = "0.4.0" Onlin

jabu 12 Dec 17, 2022
zzhack-cli is a Command Tool to help you quickly generate a WASM WebApp with simple configuration and zero code

English | δΈ­ζ–‡ζ–‡ζ‘£ zzhack-cli is a Command Tool that can help you quickly generate a WASM WebApp with simple configuration and zero code. It's worth menti

null 17 Feb 9, 2023
πŸ“¦βœ¨ your favorite rust -> wasm workflow tool!

?? ✨ wasm-pack Your favorite Rust β†’ Wasm workflow tool! Docs | Contributing | Chat Built with ?? ?? by The Rust and WebAssembly Working Group About Th

Rust and WebAssembly 4.8k Jan 5, 2023