Skip to content

Commit

Permalink
Change atmospheric units to meters
Browse files Browse the repository at this point in the history
  • Loading branch information
mate-h committed Jan 18, 2025
1 parent 7cae04b commit c6ccb9a
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 38 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/atmosphere/aerial_view_lut.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main(@builtin(global_invocation_id) idx: vec3<u32>) {
for (var step_i: i32 = i32(settings.aerial_view_lut_samples - 1); step_i >= 0; step_i--) {
let sample_depth = depth_at_sample(slice_i, step_i);
//view_dir.w is the cosine of the angle between the view vector and the camera forward vector, used to correct the step length.
let t_i = -depth_ndc_to_view_z(sample_depth) / ray_dir.w * settings.scene_units_to_km;
let t_i = -depth_ndc_to_view_z(sample_depth) / ray_dir.w * settings.scene_units_to_m;
let dt = (t_i - prev_t);
prev_t = t_i;

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/atmosphere/functions.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ fn max_atmosphere_distance(r: f32, mu: f32) -> f32 {
return mix(t_top, t_bottom, f32(hits));
}

/// Assuming y=0 is the planet ground, returns the view radius in kilometers
/// Assuming y=0 is the planet ground, returns the view radius in meters
fn view_radius() -> f32 {
return view.world_position.y * settings.scene_units_to_km + atmosphere.bottom_radius;
return view.world_position.y * settings.scene_units_to_m + atmosphere.bottom_radius;
}

// We assume the `up` vector at the view position is the y axis, since the world is locally flat/level.
Expand Down
60 changes: 27 additions & 33 deletions crates/bevy_pbr/src/atmosphere/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,24 +232,18 @@ impl Plugin for AtmospherePlugin {
/// participating in Rayleigh and Mie scattering falls off roughly exponentially
/// from the planet's surface, ozone only exists in a band centered at a fairly
/// high altitude.
///
/// Note that all units are in kilometers. This is to combat precision issues,
/// since integrating very small atmospheric densities over long distances
/// might otherwise cause problems. [`AtmosphereSettings`] has a field to set
/// the conversion factor from scene units to km, which by default assumes that
/// the scene units are meters.
#[derive(Clone, Component, Reflect, ShaderType)]
#[require(AtmosphereSettings)]
pub struct Atmosphere {
/// Radius of the planet
///
/// units: km
/// units: m
pub bottom_radius: f32,

/// Radius at which we consider the atmosphere to 'end' for our
/// calculations (from center of planet)
///
/// units: km
/// units: m
pub top_radius: f32,

/// An approximation of the average albedo (or color, roughly) of the
Expand All @@ -259,37 +253,37 @@ pub struct Atmosphere {
pub ground_albedo: Vec3,

/// The rate of falloff of rayleigh particulate with respect to altitude:
/// optical density = exp(-rayleigh_density_exp_scale * altitude).
/// optical density = exp(-rayleigh_density_exp_scale * altitude in meters).
///
/// THIS VALUE MUST BE POSITIVE
///
/// units: N/A
pub rayleigh_density_exp_scale: f32,

/// The scattering optical density of rayleigh particulare, or how
/// much light it scatters per kilometer
/// The scattering optical density of rayleigh particulate, or how
/// much light it scatters per meter
///
/// units: km^-1
/// units: m^-1
pub rayleigh_scattering: Vec3,

/// The rate of falloff of mie particulate with respect to altitude:
/// optical density = exp(-mie_density_exp_scale * altitude)
/// optical density = exp(-mie_density_exp_scale * altitude in meters)
///
/// THIS VALUE MUST BE POSITIVE
///
/// units: N/A
pub mie_density_exp_scale: f32,

/// The scattering optical density of mie particular, or how much light
/// it scatters per kilometer.
/// it scatters per meter.
///
/// units: km^-1
/// units: m^-1
pub mie_scattering: f32,

/// The absorbing optical density of mie particulate, or how much light
/// it absorbs per kilometer.
/// it absorbs per meter.
///
/// units: km^-1
/// units: m^-1
pub mie_absorption: f32,

/// The "asymmetry" of mie scattering, or how much light tends to scatter
Expand All @@ -301,35 +295,35 @@ pub struct Atmosphere {

/// The altitude at which the ozone layer is centered.
///
/// units: km
/// units: m
pub ozone_layer_altitude: f32,

/// The width of the ozone layer
///
/// units: km
/// units: m
pub ozone_layer_width: f32,

/// The optical density of ozone, or how much of each wavelength of
/// light it absorbs per kilometer.
///
/// units: km^-1
/// units: m^-1
pub ozone_absorption: Vec3,
}

impl Atmosphere {
pub const EARTH: Atmosphere = Atmosphere {
bottom_radius: 6360.0,
top_radius: 6460.0,
bottom_radius: 6360_000.0,
top_radius: 6460_000.0,
ground_albedo: Vec3::splat(0.3),
rayleigh_density_exp_scale: 1.0 / 8.0,
rayleigh_scattering: Vec3::new(0.005802, 0.013558, 0.033100),
mie_density_exp_scale: 1.0 / 1.2,
mie_scattering: 0.003996,
mie_absorption: 0.0004440,
rayleigh_density_exp_scale: 1.0 / 8000.0,
rayleigh_scattering: Vec3::new(5.802e-6, 13.558e-6, 33.100e-6),
mie_density_exp_scale: 1.0 / 1200.0,
mie_scattering: 3.996e-6,
mie_absorption: 0.444e-6,
mie_asymmetry: 0.8,
ozone_layer_altitude: 25.0,
ozone_layer_width: 30.0,
ozone_absorption: Vec3::new(0.000650, 0.001881, 0.000085),
ozone_layer_altitude: 25000.0,
ozone_layer_width: 30000.0,
ozone_absorption: Vec3::new(0.650e-6, 1.881e-6, 0.085e-6),
};

pub fn with_density_multiplier(&self, mult: f32) -> Self {
Expand Down Expand Up @@ -412,9 +406,9 @@ pub struct AtmosphereSettings {
/// of the aerial-view LUT.
pub aerial_view_lut_samples: u32,

/// A conversion factor between scene units and kilometers, used to
/// A conversion factor between scene units and meters, used to
/// combat floating-point precision issues.
pub scene_units_to_km: f32,
pub scene_units_to_m: f32,
}

impl Default for AtmosphereSettings {
Expand All @@ -429,7 +423,7 @@ impl Default for AtmosphereSettings {
sky_view_lut_samples: 16,
aerial_view_lut_size: UVec3::new(32, 32, 32),
aerial_view_lut_samples: 10,
scene_units_to_km: 1.0e-3,
scene_units_to_m: 1.0,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/atmosphere/types.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct AtmosphereSettings {
multiscattering_lut_samples: u32,
sky_view_lut_samples: u32,
aerial_view_lut_samples: u32,
scene_units_to_km: f32,
scene_units_to_m: f32,
}


Expand Down
4 changes: 3 additions & 1 deletion examples/3d/atmosphere.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use bevy::{
pbr::{Atmosphere, AtmosphereSettings, CascadeShadowConfigBuilder},
prelude::*,
};
use bevy_render::camera::Exposure;
use light_consts::lux;

fn main() {
Expand All @@ -20,6 +21,7 @@ fn main() {
fn setup_camera_fog(mut commands: Commands) {
commands.spawn((
Camera3d::default(),
Exposure { ev100: 11.0 },
Camera {
hdr: true,
..default()
Expand All @@ -29,7 +31,7 @@ fn setup_camera_fog(mut commands: Commands) {
Atmosphere::EARTH,
Bloom::NATURAL,
AtmosphereSettings {
scene_units_to_km: 1.0,
scene_units_to_m: 1e+3,
..Default::default()
},
));
Expand Down

0 comments on commit c6ccb9a

Please sign in to comment.