-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
[Merged by Bors] - Add Distance and Atmospheric Fog support #6412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
014a9cb
6458025
dfbd7f6
d7afc3e
fb588a5
0d2afb9
8855bdd
f7fb67e
8c8aa79
d999308
c446fcc
2138dfc
b7c478f
db1eca0
1e7f6c3
6b8a196
6d2a41a
7de98fd
505a5a2
e13c5c3
5d8f708
e7a4a98
ddb4eb9
48295a0
7a88d0e
50f0f50
00226a3
e18f682
e4f01e2
e626862
270dcd9
8ecba3b
68447a2
a2a5b07
a4ee547
e0195d3
e830d93
a998fa8
c608a75
aeafcc7
ecea533
73ad380
3323542
92dac89
256fce6
be50d07
50a41cd
a35783a
8261011
11f1bb5
cbb330c
bf668da
e3b65c8
036fbd3
9f3b0c4
49a3f1e
f9056c0
3c9b359
e123574
2664ca1
d54dce2
ccfb0ce
6ab1188
f44e381
aa3fef7
f1cebd2
f9ceb4c
820a6b1
cd11d43
df77ce3
15afdfb
c4eb571
28f4fb0
8b99f6f
1e3ab2c
5fd6a42
8c4d4e9
4608dbd
fee838d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,10 +48,6 @@ pub fn prepare_fog( | |
| for (entity, fog) in &views { | ||
| let gpu_fog = if let Some(fog) = fog { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of using an if let else and then a match, you can use a match like Some(Linear) => ..., Some(Exponential) => ..., None => GPU_FOG_MODE_OFF.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hadn't considered using a nested match pattern... Just tried it out, I think the need for matching It would end up looking like this: let gpu_fog = match &fog {
Some(FogSettings {
falloff: FogFalloff::Linear { start, end },
color,
directional_light_color,
directional_light_exponent,
}) => GpuFog {
mode: GPU_FOG_MODE_LINEAR,
base_color: (*color).into(),
directional_light_color: (*directional_light_color).into(),
directional_light_exponent: *directional_light_exponent,
be: Vec3::new(*start, *end, 0.0),
..Default::default()
},
Some(FogSettings {
falloff: FogFalloff::Exponential { density },
color,
directional_light_color,
directional_light_exponent,
}) => GpuFog {
mode: GPU_FOG_MODE_EXPONENTIAL,
base_color: (*color).into(),
directional_light_color: (*directional_light_color).into(),
directional_light_exponent: *directional_light_exponent,
be: Vec3::new(*density, 0.0, 0.0),
..Default::default()
},
Some(FogSettings {
falloff: FogFalloff::ExponentialSquared { density },
color,
directional_light_color,
directional_light_exponent,
}) => GpuFog {
mode: GPU_FOG_MODE_EXPONENTIAL_SQUARED,
base_color: (*color).into(),
directional_light_color: (*directional_light_color).into(),
directional_light_exponent: *directional_light_exponent,
be: Vec3::new(*density, 0.0, 0.0),
..Default::default()
},
Some(FogSettings {
falloff:
FogFalloff::Atmospheric {
extinction,
inscattering,
},
color,
directional_light_color,
directional_light_exponent,
}) => GpuFog {
mode: GPU_FOG_MODE_ATMOSPHERIC,
base_color: (*color).into(),
directional_light_color: (*directional_light_color).into(),
directional_light_exponent: *directional_light_exponent,
be: *extinction,
bi: *inscattering,
},
// If no fog is added to a camera, by default it's off
None => GpuFog {
mode: GPU_FOG_MODE_OFF,
..Default::default()
},
}; |
||
| match &fog.mode { | ||
| FogMode::Off => GpuFog { | ||
| mode: GPU_FOG_MODE_OFF, | ||
| ..Default::default() | ||
| }, | ||
| FogMode::Linear { start, end } => GpuFog { | ||
| mode: GPU_FOG_MODE_LINEAR, | ||
| color: fog.color.into(), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,310 @@ | ||
| //! This example shows how to use distance fog | ||
coreh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| use bevy::{ | ||
| pbr::{NotShadowCaster, NotShadowReceiver}, | ||
| prelude::*, | ||
| }; | ||
|
|
||
| fn main() { | ||
| App::new() | ||
| .add_plugins(DefaultPlugins) | ||
| .add_startup_system(setup_camera_fog) | ||
| .add_startup_system(setup_pyramid_scene) | ||
| .add_startup_system(setup_instructions) | ||
| .add_system(update_system) | ||
| .run(); | ||
| } | ||
|
|
||
| fn setup_camera_fog(mut commands: Commands) { | ||
| commands.spawn(( | ||
| Camera3dBundle::default(), | ||
| Fog { | ||
| color: Color::rgba(0.05, 0.05, 0.05, 1.0), | ||
| mode: FogMode::Linear { | ||
| start: 5.0, | ||
| end: 20.0, | ||
| }, | ||
| }, | ||
| )); | ||
| } | ||
|
|
||
| fn setup_pyramid_scene( | ||
| mut commands: Commands, | ||
| mut meshes: ResMut<Assets<Mesh>>, | ||
| mut materials: ResMut<Assets<StandardMaterial>>, | ||
| ) { | ||
| let stone = materials.add(StandardMaterial { | ||
| base_color: Color::hex("28221B").unwrap(), | ||
| perceptual_roughness: 1.0, | ||
| ..default() | ||
| }); | ||
|
|
||
| // pillars | ||
| for (x, z) in vec![(-1.5, -1.5), (1.5, -1.5), (1.5, 1.5), (-1.5, 1.5)] { | ||
| commands.spawn(PbrBundle { | ||
| mesh: meshes.add(Mesh::from(shape::Box { | ||
| min_x: -0.5, | ||
| max_x: 0.5, | ||
| min_z: -0.5, | ||
| max_z: 0.5, | ||
| min_y: 0.0, | ||
| max_y: 3.0, | ||
| })), | ||
| material: stone.clone(), | ||
| transform: Transform::from_xyz(x, 0.0, z), | ||
| ..default() | ||
| }); | ||
| } | ||
|
|
||
| // orb | ||
| commands.spawn(( | ||
| PbrBundle { | ||
| mesh: meshes.add(Mesh::from(shape::Icosphere::default())), | ||
| material: materials.add(StandardMaterial { | ||
| base_color: Color::hex("126212CC").unwrap(), | ||
| reflectance: 1.0, | ||
| perceptual_roughness: 0.0, | ||
| metallic: 0.5, | ||
| alpha_mode: AlphaMode::Blend, | ||
| ..default() | ||
| }), | ||
| transform: Transform::from_scale(Vec3::splat(1.75)) | ||
| .with_translation(Vec3::new(0.0, 4.0, 0.0)), | ||
| ..default() | ||
| }, | ||
| NotShadowCaster, | ||
| NotShadowReceiver, | ||
| )); | ||
|
|
||
| // steps | ||
| for i in 0..50 { | ||
| let size = i as f32 / 2.0 + 3.0; | ||
| let y = -i as f32 / 2.0; | ||
| commands.spawn(PbrBundle { | ||
| mesh: meshes.add(Mesh::from(shape::Box { | ||
| min_x: -size, | ||
| max_x: size, | ||
| min_z: -size, | ||
| max_z: size, | ||
| min_y: 0.0, | ||
| max_y: 0.5, | ||
| })), | ||
| material: stone.clone(), | ||
| transform: Transform::from_xyz(0.0, y, 0.0), | ||
| ..default() | ||
| }); | ||
| } | ||
|
|
||
| // sky | ||
| commands.spawn(PbrBundle { | ||
| mesh: meshes.add(Mesh::from(shape::Box::default())), | ||
| material: materials.add(StandardMaterial { | ||
| base_color: Color::hex("28221B").unwrap(), | ||
| cull_mode: None, | ||
| perceptual_roughness: 1.0, | ||
| ..default() | ||
| }), | ||
| transform: Transform::from_scale(Vec3::splat(10_000_000.0)), | ||
| ..default() | ||
| }); | ||
|
|
||
| // light | ||
| commands.spawn(PointLightBundle { | ||
| transform: Transform::from_xyz(0.0, 1.0, 0.0), | ||
| point_light: PointLight { | ||
| intensity: 1500., | ||
| range: 100., | ||
| shadows_enabled: true, | ||
| ..default() | ||
| }, | ||
| ..default() | ||
| }); | ||
| } | ||
|
|
||
| fn setup_instructions(mut commands: Commands, asset_server: Res<AssetServer>) { | ||
| // UI camera | ||
| commands.spawn(Camera2dBundle { | ||
coreh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| camera: Camera { | ||
| priority: -1, | ||
| ..default() | ||
| }, | ||
| ..default() | ||
| }); | ||
|
|
||
| commands.spawn((TextBundle::from_section( | ||
| "", | ||
| TextStyle { | ||
| font: asset_server.load("fonts/FiraMono-Medium.ttf"), | ||
| font_size: 12.0, | ||
| color: Color::WHITE, | ||
| }, | ||
| ) | ||
| .with_style(Style { | ||
| position_type: PositionType::Absolute, | ||
| position: UiRect { | ||
| top: Val::Px(10.0), | ||
| left: Val::Px(10.0), | ||
| ..default() | ||
| }, | ||
| ..default() | ||
| }),)); | ||
| } | ||
|
|
||
| fn update_system( | ||
| mut camera: Query<(&mut Fog, &mut Transform)>, | ||
| mut text: Query<&mut Text>, | ||
| time: Res<Time>, | ||
| keycode: Res<Input<KeyCode>>, | ||
| ) { | ||
| let now = time.elapsed().as_millis() as f32 / 1000.0; | ||
| let delta = time.delta().as_millis() as f32 / 1000.0; | ||
|
|
||
| let (mut fog, mut transform) = camera.single_mut(); | ||
| let mut text = text.single_mut(); | ||
|
|
||
| // Orbit camera around pyramid | ||
| let orbit_scale = 8.0 + (now / 10.0).sin() * 7.0; | ||
| *transform = Transform::from_xyz( | ||
| (now / 5.0).cos() * orbit_scale, | ||
| 12.0 - orbit_scale / 2.0, | ||
| (now / 5.0).sin() * orbit_scale, | ||
| ) | ||
| .looking_at(Vec3::ZERO, Vec3::Y); | ||
|
|
||
| // Fog Information | ||
| text.sections[0].value = format!("Fog Mode: {:?}\nFog Color: {:?}", fog.mode, fog.color); | ||
|
|
||
| // Fog Mode Switching | ||
| text.sections[0] | ||
| .value | ||
| .push_str(format!("\n\n1 / 2 / 3 - Switch Fog Mode").as_str()); | ||
|
|
||
| if keycode.pressed(KeyCode::Key1) { | ||
| fog.mode = match fog.mode { | ||
coreh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| FogMode::Linear { start, end } => FogMode::Linear { start, end }, | ||
| _ => FogMode::Linear { | ||
| start: 5.0, | ||
| end: 20.0, | ||
| }, | ||
| }; | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::Key2) { | ||
| fog.mode = match fog.mode { | ||
| FogMode::Exponential { density } => FogMode::Exponential { density }, | ||
| FogMode::ExponentialSquared { density } => FogMode::Exponential { density }, | ||
| _ => FogMode::Exponential { density: 0.07 }, | ||
| }; | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::Key3) { | ||
| fog.mode = match fog.mode { | ||
| FogMode::Exponential { density } => FogMode::ExponentialSquared { density }, | ||
| FogMode::ExponentialSquared { density } => FogMode::ExponentialSquared { density }, | ||
| _ => FogMode::ExponentialSquared { density: 0.07 }, | ||
| }; | ||
| } | ||
|
|
||
| // Linear Fog Controls | ||
| if let FogMode::Linear { | ||
| ref mut start, | ||
| ref mut end, | ||
| } = &mut fog.mode | ||
| { | ||
| text.sections[0] | ||
| .value | ||
| .push_str(format!("\nA / S - Move Start Distance\nZ / X - Move End Distance").as_str()); | ||
|
|
||
| if keycode.pressed(KeyCode::A) { | ||
| *start -= delta * 3.0; | ||
| } | ||
| if keycode.pressed(KeyCode::S) { | ||
| *start += delta * 3.0; | ||
| } | ||
| if keycode.pressed(KeyCode::Z) { | ||
| *end -= delta * 3.0; | ||
| } | ||
| if keycode.pressed(KeyCode::X) { | ||
| *end += delta * 3.0; | ||
| } | ||
| } | ||
|
|
||
| // Exponential Fog Controls | ||
| if let FogMode::Exponential { ref mut density } = &mut fog.mode { | ||
| text.sections[0] | ||
| .value | ||
| .push_str(format!("\nA / S - Change Density").as_str()); | ||
|
|
||
| if keycode.pressed(KeyCode::A) { | ||
| *density -= delta * 0.5 * *density; | ||
| if *density < 0.0 { | ||
| *density = 0.0 | ||
| } | ||
| } | ||
| if keycode.pressed(KeyCode::S) { | ||
| *density += delta * 0.5 * *density; | ||
| } | ||
| } | ||
|
|
||
| // ExponentialSquared Fog Controls | ||
| if let FogMode::ExponentialSquared { ref mut density } = &mut fog.mode { | ||
| text.sections[0] | ||
| .value | ||
| .push_str(format!("\nA / S - Change Density").as_str()); | ||
|
|
||
| if keycode.pressed(KeyCode::A) { | ||
| *density -= delta * 0.5 * *density; | ||
| if *density < 0.0 { | ||
| *density = 0.0 | ||
| } | ||
| } | ||
| if keycode.pressed(KeyCode::S) { | ||
| *density += delta * 0.5 * *density; | ||
| } | ||
| } | ||
|
|
||
| // RGBA Controls | ||
| text.sections[0] | ||
| .value | ||
| .push_str(format!("\n\n- / = - Red\n[ / ] - Green\n; / ' - Blue\n. / ? - Alpha").as_str()); | ||
|
|
||
| if keycode.pressed(KeyCode::Minus) { | ||
| let r = (fog.color.r() - 0.1 * delta).max(0.0); | ||
| fog.color.set_r(r); | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::Equals) { | ||
| let r = (fog.color.r() + 0.1 * delta).min(1.0); | ||
| fog.color.set_r(r); | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::LBracket) { | ||
| let r = (fog.color.g() - 0.1 * delta).max(0.0); | ||
coreh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| fog.color.set_g(r); | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::RBracket) { | ||
| let r = (fog.color.g() + 0.1 * delta).min(1.0); | ||
| fog.color.set_g(r); | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::Semicolon) { | ||
| let r = (fog.color.b() - 0.1 * delta).max(0.0); | ||
| fog.color.set_b(r); | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::Apostrophe) { | ||
| let r = (fog.color.b() + 0.1 * delta).min(1.0); | ||
| fog.color.set_b(r); | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::Period) { | ||
| let r = (fog.color.a() - 0.1 * delta).max(0.0); | ||
| fog.color.set_a(r); | ||
| } | ||
|
|
||
| if keycode.pressed(KeyCode::Slash) { | ||
| let r = (fog.color.a() + 0.1 * delta).min(1.0); | ||
| fog.color.set_a(r); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.