Skip to content

Commit 20aa419

Browse files
authored
Remove z_layer_2d (#429)
Remove `ParticleEffect::z_layer_2d` in favor of just using the effect `Transform`'s Z coordinate. This makes ordering particle effects in layers (along Z) more consistent and expected. Fixes #423
1 parent 3c7a6d0 commit 20aa419

File tree

7 files changed

+13
-124
lines changed

7 files changed

+13
-124
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7878
- Removed `EffectAsset::ribbon_group` as well as `with_trails()` and `with_ribbons()`.
7979
Use the `Attribute::RIBBON_ID` instead to assign a per-particle ribbon ID.
8080
- Removed `ParticleEffectBundle`. Use `ParticleEffect` directly instead.
81+
- Removed `ParticleEffect::z_layer_2d`. Use the Z coordinate of the effect's `Tranform` to order effects.
8182

8283
## [0.14.0] 2024-12-09
8384

examples/2d.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
//! A particle system with a 2D camera.
2-
//!
3-
//! The particle effect instance override its `z_layer_2d` field, which can be
4-
//! tweaked at runtime via the egui inspector to move the 2D rendering layer of
5-
//! particle above or below the reference square.
62
73
use bevy::{prelude::*, render::camera::ScalingMode};
84
use bevy_hanabi::prelude::*;
@@ -95,15 +91,11 @@ fn setup(
9591

9692
// Spawn an instance of the particle effect, and override its Z layer to
9793
// be above the reference white square previously spawned.
98-
commands.spawn((
99-
// Assign the Z layer so it appears in the egui inspector and can be modified at runtime
100-
ParticleEffect::new(effect).with_z_layer_2d(Some(0.1)),
101-
Name::new("effect:2d"),
102-
));
94+
commands.spawn((ParticleEffect::new(effect), Name::new("effect:2d")));
10395
}
10496

10597
fn update_plane(time: Res<Time>, mut query: Query<&mut Transform, With<Mesh2d>>) {
10698
let mut transform = query.single_mut();
10799
// Move the plane back and forth to show particles ordering relative to it
108-
transform.translation.z = (time.elapsed_secs() * 2.5).sin() * 0.045 + 0.1;
100+
transform.translation.z = (time.elapsed_secs() * 2.5).sin() * 0.045;
109101
}

src/asset.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ pub struct EffectAsset {
297297
pub simulation_condition: SimulationCondition,
298298
/// Seed for the pseudo-random number generator.
299299
///
300-
/// This is uploaded to GPU and used for the various random expressions and quantities computed in shaders.
300+
/// This is uploaded to GPU and used for the various random expressions and
301+
/// quantities computed in shaders.
301302
pub prng_seed: u32,
302303
/// Init modifier defining the effect.
303304
#[reflect(ignore)]

src/lib.rs

+1-67
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,6 @@
166166
167167
use std::fmt::Write as _;
168168

169-
#[cfg(feature = "2d")]
170-
use bevy::math::FloatOrd;
171169
use bevy::{
172170
prelude::*,
173171
render::sync_world::SyncToRenderWorld,
@@ -625,55 +623,12 @@ impl From<&PropertyInstance> for PropertyValue {
625623
pub struct ParticleEffect {
626624
/// Handle of the effect to instantiate.
627625
pub handle: Handle<EffectAsset>,
628-
/// For 2D rendering, override the value of the Z coordinate of the layer at
629-
/// which the particles are rendered.
630-
///
631-
/// This value is passed to the render pipeline and used when sorting
632-
/// transparent items to render, to order them. As a result, effects
633-
/// with different Z values cannot be batched together, which may
634-
/// negatively affect performance.
635-
///
636-
/// Note that this value is shared by all particles of the effect instance.
637-
///
638-
/// This is only available with the `2d` feature.
639-
#[cfg(feature = "2d")]
640-
pub z_layer_2d: Option<f32>,
641626
}
642627

643628
impl ParticleEffect {
644629
/// Create a new particle effect without a spawner or any modifier.
645630
pub fn new(handle: Handle<EffectAsset>) -> Self {
646-
Self {
647-
handle,
648-
#[cfg(feature = "2d")]
649-
z_layer_2d: None,
650-
}
651-
}
652-
653-
/// Set the value of the Z layer used when rendering in 2D mode.
654-
///
655-
/// In 2D mode, the Bevy renderer sorts all render items according to their
656-
/// Z layer value, from back (negative) to front (positive). This
657-
/// function sets the value assigned to the current particle effect, to
658-
/// order it relative to any other 2D render item (including non-effects).
659-
/// Setting the value to `None` reverts to the default sorting and put the
660-
/// effect back into the default layer.
661-
///
662-
/// This function has no effect when rendering in 3D mode.
663-
///
664-
/// # Example
665-
///
666-
/// ```
667-
/// # use bevy_hanabi::*;
668-
/// # use bevy::asset::Handle;
669-
/// # let asset = Handle::<EffectAsset>::default();
670-
/// // Always render the effect in front of the default layer (z=0)
671-
/// let effect = ParticleEffect::new(asset).with_z_layer_2d(Some(0.1));
672-
/// ```
673-
#[cfg(feature = "2d")]
674-
pub fn with_z_layer_2d(mut self, z_layer_2d: Option<f32>) -> Self {
675-
self.z_layer_2d = z_layer_2d;
676-
self
631+
Self { handle }
677632
}
678633
}
679634

@@ -1323,9 +1278,6 @@ pub struct CompiledParticleEffect {
13231278
effect_shader: Option<EffectShader>,
13241279
/// Textures used by the effect, if any.
13251280
textures: Vec<Handle<Image>>,
1326-
/// 2D layer for the effect instance.
1327-
#[cfg(feature = "2d")]
1328-
z_layer_2d: FloatOrd,
13291281
/// Layout flags.
13301282
layout_flags: LayoutFlags,
13311283
/// Alpha mode.
@@ -1346,8 +1298,6 @@ impl Default for CompiledParticleEffect {
13461298
mesh: None,
13471299
effect_shader: None,
13481300
textures: vec![],
1349-
#[cfg(feature = "2d")]
1350-
z_layer_2d: FloatOrd(0.0),
13511301
layout_flags: LayoutFlags::NONE,
13521302
alpha_mode: default(),
13531303
parent_particle_layout: None,
@@ -1368,7 +1318,6 @@ impl CompiledParticleEffect {
13681318
pub(crate) fn update(
13691319
&mut self,
13701320
rebuild: bool,
1371-
#[cfg(feature = "2d")] z_layer_2d: FloatOrd,
13721321
instance: &ParticleEffect,
13731322
material: Option<&EffectMaterial>,
13741323
asset: &EffectAsset,
@@ -1407,12 +1356,6 @@ impl CompiledParticleEffect {
14071356
// smarter here, only invalidate what changed, but for now just wipe everything
14081357
// and rebuild from scratch all three shaders together.
14091358
self.effect_shader = None;
1410-
1411-
// Update the 2D layer
1412-
#[cfg(feature = "2d")]
1413-
{
1414-
self.z_layer_2d = z_layer_2d;
1415-
}
14161359
}
14171360

14181361
// If the shaders are already compiled, there's nothing more to do
@@ -1726,17 +1669,8 @@ fn compile_effects(
17261669
debug!("Invalidating the compiled cache for effect on entity {:?} due to changes in the ParticleEffect component. If you see this message too much, then performance might be affected. Find why the change detection of the ParticleEffect is triggered.", entity);
17271670
}
17281671

1729-
#[cfg(feature = "2d")]
1730-
let z_layer_2d = effect
1731-
.z_layer_2d
1732-
.map_or(FloatOrd(asset.z_layer_2d), |z_layer_2d| {
1733-
FloatOrd(z_layer_2d)
1734-
});
1735-
17361672
compiled_effect.update(
17371673
need_rebuild,
1738-
#[cfg(feature = "2d")]
1739-
z_layer_2d,
17401674
&effect,
17411675
material.map(|r| r.into_inner()),
17421676
asset,

src/render/batch.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use std::{collections::VecDeque, fmt::Debug, num::NonZeroU32, ops::Range};
22

3-
#[cfg(feature = "2d")]
4-
use bevy::math::FloatOrd;
53
use bevy::{
64
prelude::*,
75
render::{
@@ -322,14 +320,8 @@ pub(crate) struct EffectDrawBatch {
322320
/// Note: currently there's a 1:1 mapping between effect batch and draw
323321
/// batch.
324322
pub effect_batch_index: EffectBatchIndex,
325-
/// For 2D rendering, the Z coordinate used as the sort key. Ignored for 3D
326-
/// rendering.
327-
#[cfg(feature = "2d")]
328-
pub z_sort_key_2d: FloatOrd,
329-
/// For 3d rendering, the position of the emitter so we can compute distance
330-
/// to camera. Ignored for 2D rendering.
331-
#[cfg(feature = "3d")]
332-
pub translation_3d: Vec3,
323+
/// Position of the emitter so we can compute distance to camera.
324+
pub translation: Vec3,
333325
}
334326

335327
impl EffectBatch {
@@ -429,15 +421,11 @@ pub(crate) struct BatchInput {
429421
pub spawner_base: u32,
430422
/// Number of particles to spawn for this effect.
431423
pub spawn_count: u32,
432-
/// Emitter position, for 3D sorting.
433-
#[cfg(feature = "3d")]
424+
/// Emitter position.
434425
pub position: Vec3,
435426
/// Index of the init indirect dispatch struct, if any.
436427
// FIXME - Contains a single effect's data; should handle multiple ones.
437428
pub init_indirect_dispatch_index: Option<u32>,
438-
/// Sort key, for 2D only.
439-
#[cfg(feature = "2d")]
440-
pub z_sort_key_2d: FloatOrd,
441429
}
442430

443431
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

src/render/mod.rs

+4-27
Original file line numberDiff line numberDiff line change
@@ -2185,10 +2185,6 @@ pub(crate) struct ExtractedEffect {
21852185
pub alpha_mode: AlphaMode,
21862186
/// Effect shaders.
21872187
pub effect_shaders: EffectShader,
2188-
/// For 2D rendering, the Z coordinate used as the sort key. Ignored for 3D
2189-
/// rendering.
2190-
#[cfg(feature = "2d")]
2191-
pub z_sort_key_2d: FloatOrd,
21922188
}
21932189

21942190
pub struct AddedEffectParent {
@@ -2519,9 +2515,6 @@ pub(crate) fn extract_effects(
25192515
None
25202516
};
25212517

2522-
#[cfg(feature = "2d")]
2523-
let z_sort_key_2d = compiled_effect.z_layer_2d;
2524-
25252518
let property_layout = asset.property_layout();
25262519
let property_data = if let Some(properties) = maybe_properties {
25272520
// Note: must check that property layout is not empty, because the
@@ -2571,8 +2564,6 @@ pub(crate) fn extract_effects(
25712564
textures: compiled_effect.textures.clone(),
25722565
alpha_mode,
25732566
effect_shaders: effect_shaders.clone(),
2574-
#[cfg(feature = "2d")]
2575-
z_sort_key_2d,
25762567
});
25772568
}
25782569
}
@@ -3926,10 +3917,6 @@ pub(crate) fn prepare_effects(
39263917
);
39273918
trace!("layout_flags = {:?}", extracted_effect.layout_flags);
39283919
trace!("particle_layout = {:?}", effect_slice.particle_layout);
3929-
#[cfg(feature = "2d")]
3930-
{
3931-
trace!("z_sort_key_2d = {:?}", extracted_effect.z_sort_key_2d);
3932-
}
39333920

39343921
let spawner_index = effects_meta.allocate_spawner(
39353922
&extracted_effect.transform,
@@ -3962,12 +3949,9 @@ pub(crate) fn prepare_effects(
39623949
shaders: extracted_effect.effect_shaders,
39633950
spawner_base: spawner_index,
39643951
spawn_count: extracted_effect.spawn_count,
3965-
#[cfg(feature = "3d")]
39663952
position: extracted_effect.transform.translation(),
39673953
init_indirect_dispatch_index: cached_child_info
39683954
.map(|cc| cc.init_indirect_dispatch_index),
3969-
#[cfg(feature = "2d")]
3970-
z_sort_key_2d: extracted_effect.z_sort_key_2d,
39713955
});
39723956

39733957
// Update properties
@@ -4238,11 +4222,7 @@ pub(crate) fn batch_effects(
42384222
// continue;
42394223
// }
42404224

4241-
#[cfg(feature = "2d")]
4242-
let z_sort_key_2d = input.z_sort_key_2d;
4243-
4244-
#[cfg(feature = "3d")]
4245-
let translation_3d = input.position;
4225+
let translation = input.position;
42464226

42474227
// Spawn one EffectBatch per instance (no batching; TODO). This contains
42484228
// most of the data needed to drive rendering. However this doesn't drive
@@ -4340,10 +4320,7 @@ pub(crate) fn batch_effects(
43404320
commands
43414321
.spawn(EffectDrawBatch {
43424322
effect_batch_index,
4343-
#[cfg(feature = "2d")]
4344-
z_sort_key_2d,
4345-
#[cfg(feature = "3d")]
4346-
translation_3d,
4323+
translation,
43474324
})
43484325
.insert(TemporaryRenderEntity);
43494326
}
@@ -5273,7 +5250,7 @@ pub(crate) fn queue_effects(
52735250
&render_meshes,
52745251
&pipeline_cache,
52755252
|id, entity, draw_batch, _view| Transparent2d {
5276-
sort_key: draw_batch.z_sort_key_2d,
5253+
sort_key: FloatOrd(draw_batch.translation.z),
52775254
entity,
52785255
pipeline: id,
52795256
draw_function: draw_effects_function_2d,
@@ -5318,7 +5295,7 @@ pub(crate) fn queue_effects(
53185295
entity,
53195296
distance: view
53205297
.rangefinder3d()
5321-
.distance_translation(&batch.translation_3d),
5298+
.distance_translation(&batch.translation),
53225299
batch_range: 0..1,
53235300
extra_index: PhaseItemExtraIndex::NONE,
53245301
},

src/spawn.rs

-4
Original file line numberDiff line numberDiff line change
@@ -971,17 +971,13 @@ mod test {
971971
InheritedVisibility::default(),
972972
ParticleEffect {
973973
handle: handle.clone(),
974-
#[cfg(feature = "2d")]
975-
z_layer_2d: None,
976974
},
977975
))
978976
.id()
979977
} else {
980978
world
981979
.spawn((ParticleEffect {
982980
handle: handle.clone(),
983-
#[cfg(feature = "2d")]
984-
z_layer_2d: None,
985981
},))
986982
.id()
987983
};

0 commit comments

Comments
 (0)