#粒子 #片段着色器 #着色器 #2D #bevy #游戏引擎

bevy_enoki

2D粒子系统插件,在wasm中表现良好

4个版本

0.2.2 2024年7月18日
0.2.1 2024年7月7日
0.2.0 2024年7月5日
0.1.0 2024年3月30日

#198 in 游戏开发

Download history 38/week @ 2024-04-25 61/week @ 2024-05-02 86/week @ 2024-05-09 21/week @ 2024-05-16 70/week @ 2024-05-23 13/week @ 2024-05-30 73/week @ 2024-06-06 23/week @ 2024-06-13 22/week @ 2024-06-20 3/week @ 2024-06-27 242/week @ 2024-07-04 40/week @ 2024-07-11 107/week @ 2024-07-18 52/week @ 2024-07-25 18/week @ 2024-08-01 8/week @ 2024-08-08

185 每月下载量

MIT 许可证

6MB
1.5K SLoC

Bevy Enoki

License: MIT or Apache 2.0 Crate

Enoki - 为Bevy游戏引擎提供的2D粒子系统。

animation

概述

Enoki粒子系统是一个CPU计算的粒子系统,它使用GPU Instancing,并且与wasm兼容性良好。它提供了一个material trait,允许您轻松实现自己的片段着色器来满足所有VFX需求。此外,通过ron文件提供spawner配置,可以热重载。

默认材质不仅支持自定义纹理,还支持在粒子生命周期内的精灵表动画。

🚧 此插件刚刚发布,仍在积极开发中。粒子行为非常基础,性能可能更好。预期会有快速变化。计划中包括轨道速度、吸引力和简单的物理。当2D完善到最佳状态时,可能会实现3D。

兼容性

bevy bevy_enoki
0.14 0.2.2
0.13 0.1

编辑器

请查看新的基于Web的粒子编辑器:Enoki粒子编辑器。通过导入和导出Ron配置,轻松调整您的效果。

示例

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

用法

bevy_enoki依赖项添加到您的Cargo.toml

bevy_enoki = "0.1"

EnokiPlugin添加到您的应用程序

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

创建第一个粒子生成器。 这里是一个默认效果配置

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()
        },
    ));
}

创建自定义材质

就像其他任何Bevy材质一样,您可以定义自己的片段着色器。

#[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()
}

现在创建着色器

//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;
}

这就完成了,现在将材质添加到您的生成器中!这些是顶点着色器提供的值

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,
};

效果资产

这里是一个默认的ron配置

#[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>>,
}

这是如何创建Curve。目前支持LinearRgbaf32RVal代表具有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);

依赖关系

~37–76MB
~1.5M SLoC