When a light goes through a transparent object, we can control how much light that will be absorbed.
To do this, we use attenuation_distance and attenuation_color in StandardMaterial.
commands.spawn(PbrBundle {
material: materials.add(StandardMaterial {
attenuation_distance: 1.,
attenuation_color: Color::BLACK,
..default()
}),
..default()
});
The value of attenuation_distance is at least 0
and can be up to infinity.
The value means: when a light goes through the object, it is absorbed after it has walked for the attenuation_distance.
The attenuation_color specifies the color of light that will not be absorbed no matter what the attenuation_distance is.
In the following example, we create three cubes.
From the left to right, their attenuation_distance are infinity
, 1
and 0.1
respectively.
All attenuation_colors are black, which means all light should be absorbed after the attenuation_distance.
To make the difference obvious, we set all specular_transmission and thickness to 1
.
We also create an orange plane with a texture board.png and disable all shadows.
The full code is as follows:
use bevy::{
app::{App, Startup},
asset::{AssetServer, Assets},
core_pipeline::core_3d::Camera3dBundle,
ecs::system::{Commands, Res, ResMut},
math::Vec3,
pbr::{DirectionalLight, DirectionalLightBundle, PbrBundle, StandardMaterial},
render::{
color::Color,
mesh::{
shape::{Cube, Plane},
Mesh,
},
},
transform::components::Transform,
utils::default,
DefaultPlugins,
};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0., 2., 3.).looking_at(Vec3::new(0., 0.5, 0.), Vec3::Y),
..default()
});
// left
commands.spawn(PbrBundle {
mesh: meshes.add(Cube::new(1.).into()),
material: materials.add(StandardMaterial {
specular_transmission: 1.,
thickness: 1.,
attenuation_distance: f32::INFINITY,
attenuation_color: Color::BLACK,
..default()
}),
transform: Transform::from_xyz(-1.25, 0.5, 0.),
..default()
});
// middle
commands.spawn(PbrBundle {
mesh: meshes.add(Cube::new(1.).into()),
material: materials.add(StandardMaterial {
specular_transmission: 1.,
thickness: 1.,
attenuation_distance: 1.,
attenuation_color: Color::BLACK,
..default()
}),
transform: Transform::from_xyz(0., 0.5, 0.),
..default()
});
// right
commands.spawn(PbrBundle {
mesh: meshes.add(Cube::new(1.).into()),
material: materials.add(StandardMaterial {
specular_transmission: 1.,
thickness: 1.,
attenuation_distance: 0.1,
attenuation_color: Color::BLACK,
..default()
}),
transform: Transform::from_xyz(1.25, 0.5, 0.),
..default()
});
commands.spawn(PbrBundle {
mesh: meshes.add(Plane::from_size(5.).into()),
material: materials.add(StandardMaterial {
base_color: Color::ORANGE,
base_color_texture: Some(asset_server.load("board.png")),
..default()
}),
..default()
});
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 50000.,
..default()
},
transform: Transform::default().looking_to(Vec3::new(-1., -1., -1.), Vec3::Y),
..default()
});
}
Result:
➡️ Next: Emissive
📘 Back: Table of contents