Skip to content

Commit 25219a4

Browse files
committed
Add transparency examples (#3695)
Adds examples demonstrating transparency for 2d, 3d and UI. Fixes #3215.
1 parent 92ddfe8 commit 25219a4

File tree

5 files changed

+230
-0
lines changed

5 files changed

+230
-0
lines changed

Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ path = "examples/2d/text2d.rs"
171171
name = "texture_atlas"
172172
path = "examples/2d/texture_atlas.rs"
173173

174+
[[example]]
175+
name = "transparency_2d"
176+
path = "examples/2d/transparency_2d.rs"
177+
174178
# 3D Rendering
175179
[[example]]
176180
name = "3d_scene"
@@ -228,6 +232,10 @@ path = "examples/3d/split_screen.rs"
228232
name = "texture"
229233
path = "examples/3d/texture.rs"
230234

235+
[[example]]
236+
name = "transparency_3d"
237+
path = "examples/3d/transparency_3d.rs"
238+
231239
[[example]]
232240
name = "two_passes"
233241
path = "examples/3d/two_passes.rs"
@@ -614,6 +622,10 @@ path = "examples/ui/text.rs"
614622
name = "text_debug"
615623
path = "examples/ui/text_debug.rs"
616624

625+
[[example]]
626+
name = "transparency_ui"
627+
path = "examples/ui/transparency_ui.rs"
628+
617629
[[example]]
618630
name = "ui"
619631
path = "examples/ui/ui.rs"

examples/2d/transparency_2d.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//! Demonstrates how to use transparency in 2D.
2+
//! Shows 3 bevy logos on top of each other, each with a different amount of transparency.
3+
4+
use bevy::prelude::*;
5+
6+
fn main() {
7+
App::new()
8+
.add_plugins(DefaultPlugins)
9+
.add_startup_system(setup)
10+
.run();
11+
}
12+
13+
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
14+
commands.spawn_bundle(Camera2dBundle::default());
15+
16+
let sprite_handle = asset_server.load("branding/icon.png");
17+
18+
commands.spawn_bundle(SpriteBundle {
19+
texture: sprite_handle.clone(),
20+
..Default::default()
21+
});
22+
commands.spawn_bundle(SpriteBundle {
23+
sprite: Sprite {
24+
// Alpha channel of the color controls transparency.
25+
color: Color::rgba(0.0, 0.0, 1.0, 0.7),
26+
..Default::default()
27+
},
28+
texture: sprite_handle.clone(),
29+
transform: Transform::from_xyz(100.0, 0.0, 0.0),
30+
..Default::default()
31+
});
32+
commands.spawn_bundle(SpriteBundle {
33+
sprite: Sprite {
34+
color: Color::rgba(0.0, 1.0, 0.0, 0.3),
35+
..Default::default()
36+
},
37+
texture: sprite_handle,
38+
transform: Transform::from_xyz(200.0, 0.0, 0.0),
39+
..Default::default()
40+
});
41+
}

examples/3d/transparency_3d.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//! Demonstrates how to use transparency in 3D.
2+
//! Shows the effects of different blend modes.
3+
//! The `fade_transparency` system smoothly changes the transparency over time.
4+
5+
use bevy::prelude::*;
6+
7+
fn main() {
8+
App::new()
9+
.insert_resource(Msaa { samples: 4 })
10+
.add_plugins(DefaultPlugins)
11+
.add_startup_system(setup)
12+
.add_system(fade_transparency)
13+
.run();
14+
}
15+
16+
#[derive(Component)]
17+
pub struct FadeTransparency;
18+
19+
fn setup(
20+
mut commands: Commands,
21+
mut meshes: ResMut<Assets<Mesh>>,
22+
mut materials: ResMut<Assets<StandardMaterial>>,
23+
) {
24+
// Opaque plane
25+
commands.spawn_bundle(PbrBundle {
26+
mesh: meshes.add(Mesh::from(shape::Plane { size: 6.0 })),
27+
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
28+
..Default::default()
29+
});
30+
// transparent sphere, using alpha_mode: Mask
31+
commands.spawn_bundle(PbrBundle {
32+
mesh: meshes.add(Mesh::from(shape::Icosphere {
33+
radius: 0.5,
34+
subdivisions: 3,
35+
})),
36+
material: materials.add(StandardMaterial {
37+
// Alpha channel of the color controls transparency.
38+
// We set it to 0.0 here, because it will be changed over time in the
39+
// `fade_transparency` function.
40+
// Note that the transparency has no effect on the objects shadow.
41+
base_color: Color::rgba(0.2, 0.7, 0.1, 0.0),
42+
// Maks sets a cutoff for transparency. Alpha values below are fully transparent,
43+
// alpha values above are fully opaque.
44+
alpha_mode: AlphaMode::Mask(0.5),
45+
..default()
46+
}),
47+
transform: Transform::from_xyz(1.0, 0.5, -1.5),
48+
..Default::default()
49+
});
50+
// transparent cube, using alpha_mode: Blend
51+
commands.spawn_bundle(PbrBundle {
52+
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
53+
// Notice how there is no need to set the `alpha_mode` explicitly here.
54+
// When converting a color to a material using `into()`, the alpha mode is
55+
// automatically set to `Blend` if the alpha channel is anything lower than 1.0.
56+
material: materials.add(Color::rgba(0.5, 0.5, 1.0, 0.0).into()),
57+
transform: Transform::from_xyz(0.0, 0.5, 0.0),
58+
..Default::default()
59+
});
60+
// sphere
61+
commands.spawn_bundle(PbrBundle {
62+
mesh: meshes.add(Mesh::from(shape::Icosphere {
63+
radius: 0.5,
64+
subdivisions: 3,
65+
})),
66+
material: materials.add(Color::rgb(0.7, 0.2, 0.1).into()),
67+
transform: Transform::from_xyz(0.0, 0.5, -1.5),
68+
..Default::default()
69+
});
70+
// light
71+
commands.spawn_bundle(PointLightBundle {
72+
point_light: PointLight {
73+
intensity: 1500.0,
74+
shadows_enabled: true,
75+
..Default::default()
76+
},
77+
transform: Transform::from_xyz(4.0, 8.0, 4.0),
78+
..Default::default()
79+
});
80+
// camera
81+
commands.spawn_bundle(Camera3dBundle {
82+
transform: Transform::from_xyz(-2.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
83+
..Default::default()
84+
});
85+
}
86+
87+
/// Fades the alpha channel of all materials between 0 and 1 over time.
88+
/// Each blend mode responds differently to this:
89+
/// - `Opaque`: Ignores alpha channel altogether, these materials stay completely opaque.
90+
/// - `Mask(f32)`: Object appears when the alpha value goes above the mask's threshold, disappears
91+
/// when the alpha value goes back below the threshold.
92+
/// - `Blend`: Object fades in and out smoothly.
93+
pub fn fade_transparency(time: Res<Time>, mut materials: ResMut<Assets<StandardMaterial>>) {
94+
let alpha = (time.time_since_startup().as_secs_f32().sin() / 2.0) + 0.5;
95+
for (_, material) in materials.iter_mut() {
96+
material.base_color.set_a(alpha);
97+
}
98+
}

examples/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Example | File | Description
9797
`sprite_flipping` | [`2d/sprite_flipping.rs`](./2d/sprite_flipping.rs) | Renders a sprite flipped along an axis
9898
`texture_atlas` | [`2d/texture_atlas.rs`](./2d/texture_atlas.rs) | Generates a texture atlas (sprite sheet) from individual sprites
9999
`rotation` | [`2d/rotation.rs`](./2d/rotation.rs) | Demonstrates rotating entities in 2D with quaternions
100+
`transparency_2d` | [`2d/transparency_2d.rs`](./2d/transparency_2d.rs) | Demonstrates transparency in 2d
100101

101102
## 3D Rendering
102103

@@ -116,6 +117,7 @@ Example | File | Description
116117
`spherical_area_lights` | [`3d/spherical_area_lights.rs`](./3d/spherical_area_lights.rs) | Demonstrates how point light radius values affect light behavior.
117118
`split_screen` | [`3d/split_screen.rs`](./3d/split_screen.rs) | Demonstrates how to render two cameras to the same window to accomplish "split screen".
118119
`texture` | [`3d/texture.rs`](./3d/texture.rs) | Shows configuration of texture materials
120+
`transparency_3d` | [`3d/transparency_3d.rs`](./3d/transparency_3d.rs) | Demonstrates transparency in 3d
119121
`two_passes` | [`3d/two_passes.rs`](./3d/two_passes.rs) | Renders two 3d passes to the same window from different perspectives.
120122
`update_gltf_scene` | [`3d/update_gltf_scene.rs`](./3d/update_gltf_scene.rs) | Update a scene from a gltf file, either by spawning the scene as a child of another entity, or by accessing the entities of the scene
121123
`vertex_colors` | [`3d/vertex_colors.rs`](./3d/vertex_colors.rs) | Shows the use of vertex colors
@@ -309,6 +311,7 @@ Example | File | Description
309311
`font_atlas_debug` | [`ui/font_atlas_debug.rs`](./ui/font_atlas_debug.rs) | Illustrates how FontAtlases are populated (used to optimize text rendering internally)
310312
`text` | [`ui/text.rs`](./ui/text.rs) | Illustrates creating and updating text
311313
`text_debug` | [`ui/text_debug.rs`](./ui/text_debug.rs) | An example for debugging text layout
314+
`transparency_ui` | [`ui/transparency_ui.rs`](./ui/transparency_ui.rs) | Demonstrates transparency for UI
312315
`ui` | [`ui/ui.rs`](./ui/ui.rs) | Illustrates various features of Bevy UI
313316

314317
## Window

examples/ui/transparency_ui.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//! Demonstrates how to use transparency with UI.
2+
//! Shows two colored buttons with transparent text.
3+
4+
use bevy::prelude::*;
5+
6+
fn main() {
7+
App::new()
8+
.insert_resource(ClearColor(Color::BLACK))
9+
.add_plugins(DefaultPlugins)
10+
.add_startup_system(setup)
11+
.run();
12+
}
13+
14+
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
15+
commands.spawn_bundle(Camera2dBundle::default());
16+
17+
let font_handle = asset_server.load("fonts/FiraSans-Bold.ttf");
18+
19+
commands
20+
.spawn_bundle(ButtonBundle {
21+
style: Style {
22+
size: Size::new(Val::Px(150.0), Val::Px(65.0)),
23+
margin: UiRect::all(Val::Auto),
24+
justify_content: JustifyContent::Center,
25+
align_items: AlignItems::Center,
26+
..Default::default()
27+
},
28+
color: Color::rgb(0.1, 0.5, 0.1).into(),
29+
..Default::default()
30+
})
31+
.with_children(|parent| {
32+
parent.spawn_bundle(TextBundle {
33+
text: Text::with_section(
34+
"Button 1",
35+
TextStyle {
36+
font: font_handle.clone(),
37+
font_size: 40.0,
38+
// Alpha channel of the color controls transparency.
39+
color: Color::rgba(1.0, 1.0, 1.0, 0.2),
40+
},
41+
Default::default(),
42+
),
43+
..Default::default()
44+
});
45+
});
46+
47+
// Button with a different color,
48+
// to demonstrate the text looks different due to its transparency.
49+
commands
50+
.spawn_bundle(ButtonBundle {
51+
style: Style {
52+
size: Size::new(Val::Px(150.0), Val::Px(65.0)),
53+
margin: UiRect::all(Val::Auto),
54+
justify_content: JustifyContent::Center,
55+
align_items: AlignItems::Center,
56+
..Default::default()
57+
},
58+
color: Color::rgb(0.5, 0.1, 0.5).into(),
59+
..Default::default()
60+
})
61+
.with_children(|parent| {
62+
parent.spawn_bundle(TextBundle {
63+
text: Text::with_section(
64+
"Button 2",
65+
TextStyle {
66+
font: font_handle.clone(),
67+
font_size: 40.0,
68+
// Alpha channel of the color controls transparency.
69+
color: Color::rgba(1.0, 1.0, 1.0, 0.2),
70+
},
71+
Default::default(),
72+
),
73+
..Default::default()
74+
});
75+
});
76+
}

0 commit comments

Comments
 (0)