Skip to content

Commit

Permalink
Add transparency examples (bevyengine#3695)
Browse files Browse the repository at this point in the history
Adds examples demonstrating transparency for 2d, 3d and UI.

Fixes bevyengine#3215.
  • Loading branch information
Wcubed authored and ItsDoot committed Feb 1, 2023
1 parent 6c0f764 commit 28dfdac
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ path = "examples/2d/text2d.rs"
name = "texture_atlas"
path = "examples/2d/texture_atlas.rs"

[[example]]
name = "transparency_2d"
path = "examples/2d/transparency_2d.rs"

# 3D Rendering
[[example]]
name = "3d_scene"
Expand Down Expand Up @@ -228,6 +232,10 @@ path = "examples/3d/split_screen.rs"
name = "texture"
path = "examples/3d/texture.rs"

[[example]]
name = "transparency_3d"
path = "examples/3d/transparency_3d.rs"

[[example]]
name = "two_passes"
path = "examples/3d/two_passes.rs"
Expand Down Expand Up @@ -614,6 +622,10 @@ path = "examples/ui/text.rs"
name = "text_debug"
path = "examples/ui/text_debug.rs"

[[example]]
name = "transparency_ui"
path = "examples/ui/transparency_ui.rs"

[[example]]
name = "ui"
path = "examples/ui/ui.rs"
Expand Down
41 changes: 41 additions & 0 deletions examples/2d/transparency_2d.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//! Demonstrates how to use transparency in 2D.
//! Shows 3 bevy logos on top of each other, each with a different amount of transparency.
use bevy::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera2dBundle::default());

let sprite_handle = asset_server.load("branding/icon.png");

commands.spawn_bundle(SpriteBundle {
texture: sprite_handle.clone(),
..Default::default()
});
commands.spawn_bundle(SpriteBundle {
sprite: Sprite {
// Alpha channel of the color controls transparency.
color: Color::rgba(0.0, 0.0, 1.0, 0.7),
..Default::default()
},
texture: sprite_handle.clone(),
transform: Transform::from_xyz(100.0, 0.0, 0.0),
..Default::default()
});
commands.spawn_bundle(SpriteBundle {
sprite: Sprite {
color: Color::rgba(0.0, 1.0, 0.0, 0.3),
..Default::default()
},
texture: sprite_handle,
transform: Transform::from_xyz(200.0, 0.0, 0.0),
..Default::default()
});
}
98 changes: 98 additions & 0 deletions examples/3d/transparency_3d.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//! Demonstrates how to use transparency in 3D.
//! Shows the effects of different blend modes.
//! The `fade_transparency` system smoothly changes the transparency over time.
use bevy::prelude::*;

fn main() {
App::new()
.insert_resource(Msaa { samples: 4 })
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.add_system(fade_transparency)
.run();
}

#[derive(Component)]
pub struct FadeTransparency;

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Opaque plane
commands.spawn_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 6.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..Default::default()
});
// transparent sphere, using alpha_mode: Mask
commands.spawn_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
})),
material: materials.add(StandardMaterial {
// Alpha channel of the color controls transparency.
// We set it to 0.0 here, because it will be changed over time in the
// `fade_transparency` function.
// Note that the transparency has no effect on the objects shadow.
base_color: Color::rgba(0.2, 0.7, 0.1, 0.0),
// Maks sets a cutoff for transparency. Alpha values below are fully transparent,
// alpha values above are fully opaque.
alpha_mode: AlphaMode::Mask(0.5),
..default()
}),
transform: Transform::from_xyz(1.0, 0.5, -1.5),
..Default::default()
});
// transparent cube, using alpha_mode: Blend
commands.spawn_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
// Notice how there is no need to set the `alpha_mode` explicitly here.
// When converting a color to a material using `into()`, the alpha mode is
// automatically set to `Blend` if the alpha channel is anything lower than 1.0.
material: materials.add(Color::rgba(0.5, 0.5, 1.0, 0.0).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..Default::default()
});
// sphere
commands.spawn_bundle(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
})),
material: materials.add(Color::rgb(0.7, 0.2, 0.1).into()),
transform: Transform::from_xyz(0.0, 0.5, -1.5),
..Default::default()
});
// light
commands.spawn_bundle(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
..Default::default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..Default::default()
});
// camera
commands.spawn_bundle(Camera3dBundle {
transform: Transform::from_xyz(-2.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
});
}

/// Fades the alpha channel of all materials between 0 and 1 over time.
/// Each blend mode responds differently to this:
/// - `Opaque`: Ignores alpha channel altogether, these materials stay completely opaque.
/// - `Mask(f32)`: Object appears when the alpha value goes above the mask's threshold, disappears
/// when the alpha value goes back below the threshold.
/// - `Blend`: Object fades in and out smoothly.
pub fn fade_transparency(time: Res<Time>, mut materials: ResMut<Assets<StandardMaterial>>) {
let alpha = (time.time_since_startup().as_secs_f32().sin() / 2.0) + 0.5;
for (_, material) in materials.iter_mut() {
material.base_color.set_a(alpha);
}
}
3 changes: 3 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ Example | File | Description
`sprite_flipping` | [`2d/sprite_flipping.rs`](./2d/sprite_flipping.rs) | Renders a sprite flipped along an axis
`texture_atlas` | [`2d/texture_atlas.rs`](./2d/texture_atlas.rs) | Generates a texture atlas (sprite sheet) from individual sprites
`rotation` | [`2d/rotation.rs`](./2d/rotation.rs) | Demonstrates rotating entities in 2D with quaternions
`transparency_2d` | [`2d/transparency_2d.rs`](./2d/transparency_2d.rs) | Demonstrates transparency in 2d

## 3D Rendering

Expand All @@ -116,6 +117,7 @@ Example | File | Description
`spherical_area_lights` | [`3d/spherical_area_lights.rs`](./3d/spherical_area_lights.rs) | Demonstrates how point light radius values affect light behavior.
`split_screen` | [`3d/split_screen.rs`](./3d/split_screen.rs) | Demonstrates how to render two cameras to the same window to accomplish "split screen".
`texture` | [`3d/texture.rs`](./3d/texture.rs) | Shows configuration of texture materials
`transparency_3d` | [`3d/transparency_3d.rs`](./3d/transparency_3d.rs) | Demonstrates transparency in 3d
`two_passes` | [`3d/two_passes.rs`](./3d/two_passes.rs) | Renders two 3d passes to the same window from different perspectives.
`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
`vertex_colors` | [`3d/vertex_colors.rs`](./3d/vertex_colors.rs) | Shows the use of vertex colors
Expand Down Expand Up @@ -309,6 +311,7 @@ Example | File | Description
`font_atlas_debug` | [`ui/font_atlas_debug.rs`](./ui/font_atlas_debug.rs) | Illustrates how FontAtlases are populated (used to optimize text rendering internally)
`text` | [`ui/text.rs`](./ui/text.rs) | Illustrates creating and updating text
`text_debug` | [`ui/text_debug.rs`](./ui/text_debug.rs) | An example for debugging text layout
`transparency_ui` | [`ui/transparency_ui.rs`](./ui/transparency_ui.rs) | Demonstrates transparency for UI
`ui` | [`ui/ui.rs`](./ui/ui.rs) | Illustrates various features of Bevy UI

## Window
Expand Down
76 changes: 76 additions & 0 deletions examples/ui/transparency_ui.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//! Demonstrates how to use transparency with UI.
//! Shows two colored buttons with transparent text.
use bevy::prelude::*;

fn main() {
App::new()
.insert_resource(ClearColor(Color::BLACK))
.add_plugins(DefaultPlugins)
.add_startup_system(setup)
.run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn_bundle(Camera2dBundle::default());

let font_handle = asset_server.load("fonts/FiraSans-Bold.ttf");

commands
.spawn_bundle(ButtonBundle {
style: Style {
size: Size::new(Val::Px(150.0), Val::Px(65.0)),
margin: UiRect::all(Val::Auto),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..Default::default()
},
color: Color::rgb(0.1, 0.5, 0.1).into(),
..Default::default()
})
.with_children(|parent| {
parent.spawn_bundle(TextBundle {
text: Text::with_section(
"Button 1",
TextStyle {
font: font_handle.clone(),
font_size: 40.0,
// Alpha channel of the color controls transparency.
color: Color::rgba(1.0, 1.0, 1.0, 0.2),
},
Default::default(),
),
..Default::default()
});
});

// Button with a different color,
// to demonstrate the text looks different due to its transparency.
commands
.spawn_bundle(ButtonBundle {
style: Style {
size: Size::new(Val::Px(150.0), Val::Px(65.0)),
margin: UiRect::all(Val::Auto),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..Default::default()
},
color: Color::rgb(0.5, 0.1, 0.5).into(),
..Default::default()
})
.with_children(|parent| {
parent.spawn_bundle(TextBundle {
text: Text::with_section(
"Button 2",
TextStyle {
font: font_handle.clone(),
font_size: 40.0,
// Alpha channel of the color controls transparency.
color: Color::rgba(1.0, 1.0, 1.0, 0.2),
},
Default::default(),
),
..Default::default()
});
});
}

0 comments on commit 28dfdac

Please sign in to comment.