diff --git a/Cargo.toml b/Cargo.toml index 5ba442b6c4..62be72f770 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" @@ -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" @@ -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" diff --git a/examples/2d/transparency_2d.rs b/examples/2d/transparency_2d.rs new file mode 100644 index 0000000000..9f7a1b36da --- /dev/null +++ b/examples/2d/transparency_2d.rs @@ -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) { + 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() + }); +} diff --git a/examples/3d/transparency_3d.rs b/examples/3d/transparency_3d.rs new file mode 100644 index 0000000000..ecf9f3f89a --- /dev/null +++ b/examples/3d/transparency_3d.rs @@ -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>, + mut materials: ResMut>, +) { + // 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