bevy_hanabi icon indicating copy to clipboard operation
bevy_hanabi copied to clipboard

Particles flickering

Open ghashy opened this issue 1 year ago • 3 comments

Bevy 0.10.1 bevy_hanabi - last version from git

Hello, first of all I would like to express my gratitude for this amazing crate! I can't figure out why I have the flickering in my studying project:

https://github.com/djeedai/bevy_hanabi/assets/109857267/ef1d82dc-663a-41b8-8dbd-4765ee7c634a

Slow motion:

https://github.com/djeedai/bevy_hanabi/assets/109857267/34541fef-1dbe-4555-aa04-11b66ac5ce34

I created particles with this code:

    let mut color_gradient = Gradient::new();
    color_gradient.add_key(0.0, Vec4::new(1., 0.97, 0.36, 0.0));
    color_gradient.add_key(0.03, Vec4::new(1., 0.76, 0.12, 0.5));
    color_gradient.add_key(0.05, Vec4::new(1., 0.40, 0.05, 0.95));
    color_gradient.add_key(0.07, Vec4::new(0.95, 0.24, 0.02, 0.93));
    color_gradient.add_key(0.09, Vec4::new(0.85, 0.12, 0.02, 0.91));
    color_gradient.add_key(0.11, Vec4::new(0.63, 0., 0., 0.9));

    color_gradient.add_key(0.14, Vec4::new(0.12, 0.08, 0.16, 0.8));
    color_gradient.add_key(0.2, Vec4::new(0.06, 0.02, 0.10, 0.7));
    color_gradient.add_key(1.0, Vec4::new(0., 0., 0., 0.));

    let effect = effects.add(
        EffectAsset {
            name: "RocketFlame".to_string(),
            capacity: 1000,
            spawner: Spawner::rate(70.0.into()).with_starts_active(false),
            ..default()
        }
        .init(InitLifetimeModifier {
            lifetime: 3_f32.into(),
        })
        .init(InitPositionCircleModifier {
            radius: 11.,
            ..default()
        })
        .init(InitVelocityCircleModifier {
            axis: Vec3::Z,
            speed: 30.0.into(),
            ..default()
        })
        .init(InitVelocityTangentModifier {
            speed: Value::Uniform((-20., 20.)),
            axis: Vec3::Z,
            ..default()
        })
        .render(ParticleTextureModifier {
            texture: asset_server.load("sprites/Original/Smoke.png"),
        })
        .render(SizeOverLifetimeModifier {
            gradient: Gradient::constant(Vec2::splat(25.0)),
        })
        .render(ColorOverLifetimeModifier {
            gradient: color_gradient,
        }),
    );

And spawned as children of Sprite:

        .with_children(|parent| {
            parent
                .spawn(SpriteBundle {
                    sprite: Sprite {
                        custom_size: Some(Vec2::new(53., 29.) / 1.5),
                        ..default()
                    },
                    transform: Transform::from_xyz(0., -BALL_SIZE / 2., 0.),
                    texture: asset_server
                        .load("sprites/Original/Rocket engine.png")
                        .into(),

                    ..default()
                })
                .with_children(|parent| {
                    parent.spawn((
                        RocketEngine,
                        ParticleEffectBundle {
                            effect: ParticleEffect::new(effect)
                                .with_z_layer_2d(Some(1.)),
                            ..default()
                        },
                        Name::new("RocketEngineParticles"),
                    ));
                });
        });

I'm not sure, but I guess that the particles are drawing in different order on every frame, and maybe this causes flickering

ghashy avatar Jun 06 '23 10:06 ghashy

Yes, there's no particle sorting. It's unfortunately both a critical feature and something hard to implement.

djeedai avatar Jun 06 '23 10:06 djeedai

Thanks for reply, I understood, so I I'll try to workaround this with lower transparency for now)

ghashy avatar Jun 06 '23 10:06 ghashy

Yes this is definitely your best bet. Sorry about that.

djeedai avatar Jun 06 '23 10:06 djeedai