mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
render: is_transparent flag. draw transparent object back-to-front and opaque objects front-to-back
This commit is contained in:
parent
2b8fe144a8
commit
4ba2f72572
6 changed files with 53 additions and 12 deletions
|
@ -2,6 +2,7 @@ use crate::bytes::AsBytes;
|
|||
use std::{
|
||||
cmp::Ordering,
|
||||
hash::{Hash, Hasher},
|
||||
ops::Neg,
|
||||
};
|
||||
|
||||
// working around the famous "rust float ordering" problem
|
||||
|
@ -39,3 +40,10 @@ impl Hash for FloatOrd {
|
|||
state.write(self.0.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for FloatOrd {
|
||||
type Output = FloatOrd;
|
||||
fn neg(self) -> Self::Output {
|
||||
FloatOrd(-self.0)
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ pub fn visible_entities_system(
|
|||
let camera_position = camera_transform.value.w_axis().truncate();
|
||||
|
||||
let mut no_transform_order = 0.0;
|
||||
let mut transparent_entities = Vec::new();
|
||||
for (entity, draw) in entities_query.iter_entities(world) {
|
||||
if !draw.is_visible {
|
||||
continue;
|
||||
|
@ -49,14 +50,28 @@ pub fn visible_entities_system(
|
|||
no_transform_order += 0.1;
|
||||
order
|
||||
};
|
||||
visible_entities.value.push(VisibleEntity {
|
||||
entity,
|
||||
order,
|
||||
})
|
||||
|
||||
if draw.is_transparent {
|
||||
transparent_entities.push(VisibleEntity {
|
||||
entity,
|
||||
order,
|
||||
})
|
||||
} else {
|
||||
visible_entities.value.push(VisibleEntity {
|
||||
entity,
|
||||
order,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sort opaque entities front-to-back
|
||||
visible_entities.value.sort_by_key(|e| e.order);
|
||||
|
||||
// sort transparent entities front-to-back
|
||||
transparent_entities.sort_by_key(|e|-e.order);
|
||||
visible_entities.value.extend(transparent_entities);
|
||||
|
||||
// TODO: check for big changes in visible entities len() vs capacity() (ex: 2x) and resize to prevent holding unneeded memory
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ pub enum RenderCommand {
|
|||
#[derive(Properties)]
|
||||
pub struct Draw {
|
||||
pub is_visible: bool,
|
||||
pub is_transparent: bool,
|
||||
#[property(ignore)]
|
||||
pub render_commands: Vec<RenderCommand>,
|
||||
}
|
||||
|
@ -59,6 +60,7 @@ impl Default for Draw {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
is_visible: true,
|
||||
is_transparent: false,
|
||||
render_commands: Default::default(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ impl Node for PassNode {
|
|||
};
|
||||
|
||||
let mut draw_state = DrawState::default();
|
||||
for visible_entity in visible_entities.iter().rev() {
|
||||
for visible_entity in visible_entities.iter() {
|
||||
let draw = if let Some(draw) = world.get_component::<Draw>(visible_entity.entity) {
|
||||
draw
|
||||
} else {
|
||||
|
|
|
@ -46,9 +46,12 @@ impl Default for SpriteEntity {
|
|||
..Default::default()
|
||||
},
|
||||
)]),
|
||||
draw: Draw {
|
||||
is_transparent: true,
|
||||
..Default::default()
|
||||
},
|
||||
sprite: Default::default(),
|
||||
material: Default::default(),
|
||||
draw: Default::default(),
|
||||
transform: Default::default(),
|
||||
translation: Default::default(),
|
||||
rotation: Default::default(),
|
||||
|
@ -91,10 +94,13 @@ impl Default for SpriteSheetEntity {
|
|||
..Default::default()
|
||||
},
|
||||
)]),
|
||||
draw: Draw {
|
||||
is_transparent: true,
|
||||
..Default::default()
|
||||
},
|
||||
mesh: QUAD_HANDLE,
|
||||
sprite: Default::default(),
|
||||
texture_atlas: Default::default(),
|
||||
draw: Default::default(),
|
||||
transform: Default::default(),
|
||||
translation: Default::default(),
|
||||
rotation: Default::default(),
|
||||
|
|
|
@ -31,6 +31,7 @@ fn setup(
|
|||
// this material renders the texture normally
|
||||
let material_handle = materials.add(StandardMaterial {
|
||||
albedo_texture: Some(texture_handle),
|
||||
shaded: false,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
|
@ -38,6 +39,7 @@ fn setup(
|
|||
let red_material_handle = materials.add(StandardMaterial {
|
||||
albedo: Color::rgba(1.0, 0.0, 0.0, 0.5),
|
||||
albedo_texture: Some(texture_handle),
|
||||
shaded: false,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
|
@ -45,6 +47,7 @@ fn setup(
|
|||
let blue_material_handle = materials.add(StandardMaterial {
|
||||
albedo: Color::rgba(0.0, 0.0, 1.0, 0.5),
|
||||
albedo_texture: Some(texture_handle),
|
||||
shaded: false,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
|
@ -57,6 +60,10 @@ fn setup(
|
|||
material: material_handle,
|
||||
translation: Translation::new(0.0, -1.5, 0.0),
|
||||
rotation: Rotation::from_euler_angles(0.0, std::f32::consts::PI / 3.0, 0.0),
|
||||
draw: Draw {
|
||||
is_transparent: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
// textured quad - modulated
|
||||
|
@ -65,6 +72,10 @@ fn setup(
|
|||
material: red_material_handle,
|
||||
translation: Translation::new(0.0, 0.0, 0.0),
|
||||
rotation: Rotation::from_euler_angles(0.0, std::f32::consts::PI / 3.0, 0.0),
|
||||
draw: Draw {
|
||||
is_transparent: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
// textured quad - modulated
|
||||
|
@ -73,11 +84,10 @@ fn setup(
|
|||
material: blue_material_handle,
|
||||
translation: Translation::new(0.0, 1.5, 0.0),
|
||||
rotation: Rotation::from_euler_angles(0.0, std::f32::consts::PI / 3.0, 0.0),
|
||||
..Default::default()
|
||||
})
|
||||
// light
|
||||
.add_entity(LightEntity {
|
||||
translation: Translation::new(0.0, -5.0, 0.0),
|
||||
draw: Draw {
|
||||
is_transparent: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
// camera
|
||||
|
|
Loading…
Reference in a new issue