diff --git a/assets/orange_circle.png b/assets/orange_circle.png deleted file mode 100644 index c066f32e..00000000 Binary files a/assets/orange_circle.png and /dev/null differ diff --git a/examples/additive.rs b/examples/additive.rs deleted file mode 100644 index f19ab8cb..00000000 --- a/examples/additive.rs +++ /dev/null @@ -1,123 +0,0 @@ -//! Example of additive blend mode. -//! -//! This example demonstrate how to change the blend mode for the particle renderer. - -use bevy::{ - core_pipeline::tonemapping::Tonemapping, - log::LogPlugin, - prelude::*, - render::{ - camera::Projection, render_resource::WgpuFeatures, settings::WgpuSettings, RenderPlugin, - }, -}; -#[cfg(feature = "examples_world_inspector")] -use bevy_inspector_egui::quick::WorldInspectorPlugin; - -use bevy_hanabi::prelude::*; - -fn main() -> Result<(), Box> { - let mut wgpu_settings = WgpuSettings::default(); - wgpu_settings - .features - .set(WgpuFeatures::VERTEX_WRITABLE_STORAGE, true); - - let mut app = App::default(); - app.insert_resource(ClearColor(Color::DARK_GRAY)) - .add_plugins( - DefaultPlugins - .set(LogPlugin { - level: bevy::log::Level::WARN, - filter: "bevy_hanabi=warn,additive=trace".to_string(), - update_subscriber: None, - }) - .set(RenderPlugin { - render_creation: wgpu_settings.into(), - synchronous_pipeline_compilation: false, - }) - .set(WindowPlugin { - primary_window: Some(Window { - title: "🎆 Hanabi — additive blending".to_string(), - ..default() - }), - ..default() - }), - ) - .add_plugins(HanabiPlugin); - - #[cfg(feature = "examples_world_inspector")] - app.add_plugins(WorldInspectorPlugin::default()); - - app.add_systems(Startup, setup) - .add_systems(Update, bevy::window::close_on_esc) - .run(); - - Ok(()) -} - -fn setup( - asset_server: Res, - mut commands: Commands, - mut effects: ResMut>, -) { - let camera = Camera3dBundle { - transform: Transform::from_xyz(0.0, 0.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y), - projection: Projection::Perspective(PerspectiveProjection { - fov: 90.0, - ..Default::default() - }), - tonemapping: Tonemapping::None, - ..Default::default() - }; - - commands.spawn(camera); - - let texture_handle: Handle = asset_server.load("orange_circle.png"); - - let writer = ExprWriter::new(); - - let age = writer.lit(0.).expr(); - let init_age = SetAttributeModifier::new(Attribute::AGE, age); - - let lifetime = writer.lit(5.).expr(); - let init_lifetime = SetAttributeModifier::new(Attribute::LIFETIME, lifetime); - - let init_pos = SetPositionCircleModifier { - center: writer.lit(0.).expr(), - axis: writer.lit(Vec3::Z).expr(), - radius: writer.lit(0.2).expr(), - dimension: ShapeDimension::Volume, - }; - - let init_vel = SetVelocityCircleModifier { - center: writer.lit(Vec3::ZERO).expr(), - axis: writer.lit(Vec3::Z).expr(), - speed: (writer.lit(0.2) + writer.lit(0.2) * writer.rand(ScalarType::Float)).expr(), - }; - - // Use the F32_0 attribute as a per-particle rotation value, initialized on - // spawn and constant after. The rotation angle is in radians, here randomly - // selected in [0:2*PI]. - let rotation = (writer.rand(ScalarType::Float) * writer.lit(std::f32::consts::TAU)).expr(); - let init_rotation = SetAttributeModifier::new(Attribute::F32_0, rotation); - - let size = Vec2::splat(0.8); - let effect = effects.add( - EffectAsset::new(vec![32768], Spawner::rate(5.0.into()), writer.finish()) - .with_name("additive") - .with_alpha_mode(bevy_hanabi::AlphaMode::Add) - .init(init_pos) - .init(init_vel) - .init(init_age) - .init(init_lifetime) - .init(init_rotation) - .render(ParticleTextureModifier { - texture: texture_handle, - sample_mapping: ImageSampleMapping::Modulate, - }) - .render(SetSizeModifier { size: size.into() }), - ); - - commands - .spawn(ParticleEffectBundle::new(effect)) - .insert(Name::new("effect")); -} diff --git a/src/asset.rs b/src/asset.rs index 716822a8..734b37e1 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -102,7 +102,7 @@ pub enum SimulationCondition { /// rendered during the [`Transparent2d`] render phase. /// /// [`Transparent2d`]: bevy::core_pipeline::core_2d::Transparent2d -#[derive(Debug, Default, Clone, Copy, PartialEq, Reflect, Serialize, Deserialize)] +#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Reflect, Serialize, Deserialize, Hash)] #[non_exhaustive] pub enum AlphaMode { /// Render the effect with alpha blending. diff --git a/src/render/mod.rs b/src/render/mod.rs index 3fdf8f22..94b19120 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -984,15 +984,6 @@ enum PipelineMode { Camera3d, } -#[cfg(all(feature = "2d", feature = "3d"))] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -enum AlphaBlendMode { - Alpha, - Premultiply, - Add, - Multiply, -} - #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub(crate) struct ParticleRenderPipelineKey { /// Render shader, with snippets applied, but not preprocessed yet. @@ -1012,7 +1003,7 @@ pub(crate) struct ParticleRenderPipelineKey { /// The effect is rendered with alpha masking. use_alpha_mask: bool, /// The effect needs Alpha blend. - alpha_blend_mode: AlphaBlendMode, + alpha_mode: AlphaMode, /// Key: FLIPBOOK /// The effect is rendered with flipbook texture animation based on the /// sprite index of each particle. @@ -1039,7 +1030,7 @@ impl Default for ParticleRenderPipelineKey { has_image: false, local_space_simulation: false, use_alpha_mask: false, - alpha_blend_mode: AlphaBlendMode::Alpha, + alpha_mode: AlphaMode::Blend, flipbook: false, needs_uv: false, #[cfg(all(feature = "2d", feature = "3d"))] @@ -1227,10 +1218,10 @@ impl SpecializedRenderPipeline for ParticlesRenderPipeline { TextureFormat::bevy_default() }; - let blend_state = match key.alpha_blend_mode { - AlphaBlendMode::Alpha => BlendState::ALPHA_BLENDING, - AlphaBlendMode::Premultiply => BlendState::PREMULTIPLIED_ALPHA_BLENDING, - AlphaBlendMode::Add => BlendState { + let blend_state = match key.alpha_mode { + AlphaMode::Blend => BlendState::ALPHA_BLENDING, + AlphaMode::Premultiply => BlendState::PREMULTIPLIED_ALPHA_BLENDING, + AlphaMode::Add => BlendState { color: BlendComponent { src_factor: BlendFactor::SrcAlpha, dst_factor: BlendFactor::One, @@ -1242,7 +1233,7 @@ impl SpecializedRenderPipeline for ParticlesRenderPipeline { operation: BlendOperation::Add, }, }, - AlphaBlendMode::Multiply => BlendState { + AlphaMode::Multiply => BlendState { color: BlendComponent { src_factor: BlendFactor::Dst, dst_factor: BlendFactor::OneMinusSrcAlpha, @@ -1250,6 +1241,7 @@ impl SpecializedRenderPipeline for ParticlesRenderPipeline { }, alpha: BlendComponent::OVER, }, + _ => BlendState::ALPHA_BLENDING, }; RenderPipelineDescriptor { @@ -2510,13 +2502,7 @@ fn emit_draw( let render_shader_source = &batches.render_shaders[draw_batch.group_index as usize]; trace!("Emit for group index #{}", draw_batch.group_index); - let alpha_blend_mode = match batches.alpha_mode { - AlphaMode::Blend => AlphaBlendMode::Alpha, - AlphaMode::Premultiply => AlphaBlendMode::Premultiply, - AlphaMode::Add => AlphaBlendMode::Add, - AlphaMode::Multiply => AlphaBlendMode::Multiply, - _ => AlphaBlendMode::Alpha, - }; + let alpha_mode = batches.alpha_mode; #[cfg(feature = "trace")] let _span_specialize = bevy::utils::tracing::info_span!("specialize").entered(); @@ -2529,7 +2515,7 @@ fn emit_draw( has_image, local_space_simulation, use_alpha_mask, - alpha_blend_mode, + alpha_mode, flipbook, needs_uv, #[cfg(all(feature = "2d", feature = "3d"))]