base asteroid density on actual ring density

This commit is contained in:
yuni 2024-04-02 07:05:17 +02:00
parent be55433376
commit 591db70d08
5 changed files with 110 additions and 22 deletions

View file

@ -7,7 +7,7 @@
@group(2) @binding(1) var<uniform> jupiter_radius: f32; @group(2) @binding(1) var<uniform> jupiter_radius: f32;
const jupiter_radius_Mm: f32 = 71.492; const jupiter_radius_Mm: f32 = 71.492;
const brightness = 0.05; const brightness = 0.025;
fn smooth_edge(start: f32, end: f32, value: f32) -> f32 { fn smooth_edge(start: f32, end: f32, value: f32) -> f32 {
var x: f32 = (value - start) / (end - start); var x: f32 = (value - start) / (end - start);
@ -15,6 +15,9 @@ fn smooth_edge(start: f32, end: f32, value: f32) -> f32 {
} }
fn ring_density(radius: f32) -> f32 { fn ring_density(radius: f32) -> f32 {
// NOTE: Keep this in sync with src/nature.rs::ring_density
// Input: distance to center of jupiter in million meters
// Output: relative brightness of the ring
let halo_inner: f32 = 92.0; let halo_inner: f32 = 92.0;
let halo_outer: f32 = 122.5; let halo_outer: f32 = 122.5;
let main_inner: f32 = 122.5; let main_inner: f32 = 122.5;
@ -26,13 +29,10 @@ fn ring_density(radius: f32) -> f32 {
let metis_notch_center: f32 = 128.0; let metis_notch_center: f32 = 128.0;
let metis_notch_width: f32 = 0.6; let metis_notch_width: f32 = 0.6;
let halo_brightness: f32 = 0.3; let halo_brightness: f32 = 0.75;
let main_brightness: f32 = 0.4; let main_brightness: f32 = 1.0;
let almathea_brightness: f32 = 0.2; let almathea_brightness: f32 = 0.5;
let thebe_brightness: f32 = 0.2; let thebe_brightness: f32 = 0.5;
let inner_smooth_factor: f32 = 2.0; // Smooth inner edges
let outer_smooth_factor: f32 = 1.5; // Rougher outer edges
var density: f32 = 0.0; var density: f32 = 0.0;

View file

@ -7,7 +7,7 @@ actor 0 0 0 jupiter
rotationz -0.28 rotationz -0.28
angularmomentum 30 30 30 angularmomentum 30 30 30
actor 0 0 0 suit actor 0 593051 0 suit
relativeto jupiter relativeto jupiter
orbit 220000e3 0.66 orbit 220000e3 0.66
player yes player yes

View file

@ -218,6 +218,24 @@ fn setup(
..default() ..default()
} }
), ),
TextSection::new(
"\n位置 ",
TextStyle {
font: asset_server.load(FONT),
font_size: settings.font_size_hud,
color: Color::GRAY,
..default()
},
),
TextSection::new(
"",
TextStyle {
font: asset_server.load(FONT),
font_size: settings.font_size_hud,
color: Color::GRAY,
..default()
}
),
TextSection::new( TextSection::new(
"\nSuit Integrity ", "\nSuit Integrity ",
TextStyle { TextStyle {
@ -368,7 +386,7 @@ fn update(
time: Res<Time>, time: Res<Time>,
mut log: ResMut<Log>, mut log: ResMut<Log>,
player: Query<(&actor::Suit, &actor::LifeForm), With<actor::Player>>, player: Query<(&actor::Suit, &actor::LifeForm), With<actor::Player>>,
q_camera: Query<&LinearVelocity, With<actor::PlayerCamera>>, q_camera: Query<(&Position, &LinearVelocity), With<actor::PlayerCamera>>,
mut timer: ResMut<FPSUpdateTimer>, mut timer: ResMut<FPSUpdateTimer>,
mut query: Query<&mut Text, With<GaugesText>>, mut query: Query<&mut Text, With<GaugesText>>,
q_choices: Query<&ChoiceAvailable>, q_choices: Query<&ChoiceAvailable>,
@ -382,7 +400,7 @@ fn update(
let player = player.get_single(); let player = player.get_single();
if player.is_ok() && q_camera_result.is_ok() { if player.is_ok() && q_camera_result.is_ok() {
let (suit, lifeform) = player.unwrap(); let (suit, lifeform) = player.unwrap();
let cam_v = q_camera_result.unwrap(); let (pos, cam_v) = q_camera_result.unwrap();
for mut text in &mut query { for mut text in &mut query {
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) { if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS) {
if let Some(value) = fps.smoothed() { if let Some(value) = fps.smoothed() {
@ -407,11 +425,13 @@ fn update(
text.sections[7].value = format!("{adrenaline:.0}pg/mL"); text.sections[7].value = format!("{adrenaline:.0}pg/mL");
let all_actors = query_all_actors.iter().len(); let all_actors = query_all_actors.iter().len();
text.sections[9].value = format!("{all_actors:.0}"); text.sections[9].value = format!("{all_actors:.0}");
let (x, y, z) = (pos.x, pos.y, pos.z);
text.sections[11].value = format!("{x:.0}|{z:.0}|{y:.0}");
let integrity = suit.integrity * 100.0; let integrity = suit.integrity * 100.0;
text.sections[11].value = format!("{integrity:.0}%"); text.sections[13].value = format!("{integrity:.0}%");
let speed = cam_v.length(); let speed = cam_v.length();
let kmh = speed * 60.0 * 60.0 / 1000.0; let kmh = speed * 60.0 * 60.0 / 1000.0;
text.sections[13].value = format!("{speed:.0}m/s | {kmh:.0}km/h"); text.sections[15].value = format!("{speed:.0}m/s | {kmh:.0}km/h");
} }
} }

View file

@ -32,6 +32,53 @@ pub fn star_color_index_to_rgb(color_index: f32) -> (f32, f32, f32) {
return (clamp(red), clamp(green), clamp(blue)) return (clamp(red), clamp(green), clamp(blue))
} }
fn smooth_edge(start: f32, end: f32, value: f32) -> f32 {
let x: f32 = (value - start) / (end - start);
return 4.0 * x * x * (1.0 - x * x);
}
pub fn ring_density(radius: f32) -> f32 {
// NOTE: Keep this in sync with assets/shaders/jupiters_rings.wgsl
// Input: distance to center of jupiter in million meters
// Output: relative brightness of the ring
let halo_inner: f32 = 92.0;
let halo_outer: f32 = 122.5;
let main_inner: f32 = 122.5;
let main_outer: f32 = 129.0;
let amalthea_inner: f32 = 129.0;
let amalthea_outer: f32 = 182.0;
let thebe_inner: f32 = 129.0;
let thebe_outer: f32 = 229.0;
let metis_notch_center: f32 = 128.0;
let metis_notch_width: f32 = 0.6;
let halo_brightness: f32 = 0.75;
let main_brightness: f32 = 1.0;
let almathea_brightness: f32 = 0.5;
let thebe_brightness: f32 = 0.5;
let mut density: f32 = 0.0;
if radius >= halo_inner && radius <= halo_outer {
density = halo_brightness * smooth_edge(halo_inner, halo_outer, radius);
} else if radius >= main_inner && radius <= main_outer {
let mut metis_notch_effect: f32 = 1.0;
if radius > metis_notch_center - metis_notch_width * 0.5 && radius < metis_notch_center + metis_notch_width * 0.5 {
metis_notch_effect = 0.5 * (1.0 - smooth_edge(metis_notch_center - metis_notch_width * 0.5, metis_notch_center + metis_notch_width * 0.5, radius));
}
density = main_brightness * metis_notch_effect * smooth_edge(main_inner, main_outer, radius);
} else {
if radius >= amalthea_inner && radius <= amalthea_outer {
density = almathea_brightness * smooth_edge(amalthea_inner, amalthea_outer, radius);
}
if radius >= thebe_inner && radius <= thebe_outer {
density += thebe_brightness * smooth_edge(thebe_inner, thebe_outer, radius);
}
}
return density;
}
// The "STARS" constant was autogenerated by "genrate_starchart.py" using data // The "STARS" constant was autogenerated by "genrate_starchart.py" using data
// from the HYG database: https://github.com/astronexus/HYG-Database/tree/main/hyg // from the HYG database: https://github.com/astronexus/HYG-Database/tree/main/hyg
// License: CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/ // License: CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/

View file

@ -9,7 +9,8 @@ use std::f32::consts::PI;
use fastrand; use fastrand;
const ASTEROID_UPDATE_INTERVAL: f32 = 0.1; // seconds const ASTEROID_UPDATE_INTERVAL: f32 = 0.1; // seconds
const ASTEROID_SIZE_FACTOR: f32 = 3.0; const ASTEROID_SIZE_FACTOR: f32 = 10.0;
const RING_THICKNESS: f64 = 8.0e6;
const STARS_MAX_MAGNITUDE: f32 = 5.5; const STARS_MAX_MAGNITUDE: f32 = 5.5;
const CENTER_WORLD_ON_PLAYER: bool = true; const CENTER_WORLD_ON_PLAYER: bool = true;
@ -167,9 +168,9 @@ pub fn setup(
}), }),
..default() ..default()
}, },
Position::from_xyz(0.0, -10000.0, 0.0), Position::from_xyz(0.0, 0.0, 0.0),
//Rotation::from(Quat::IDENTITY), Rotation::from(Quat::IDENTITY),
Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())), //Rotation::from(Quat::from_rotation_x(-0.3f32.to_radians())),
)); ));
} }
@ -241,6 +242,20 @@ fn spawn_despawn_asteroids(
} }
} }
// Density based on the radius alone
let radius_plane = (player.x * player.x + player.z * player.z).sqrt();
let density_r = nature::ring_density((radius_plane / 1e6) as f32);
if density_r < 0.001 {
return;
}
// Density based on radius and the vertical distance to the ring
let normalized_distance = player.y / (RING_THICKNESS / 2.0);
let density = density_r * (-4.0 * normalized_distance.powf(2.0)).exp() as f32;
dbg!(normalized_distance, density_r, density);
if density < 0.001 {
return;
}
let mut rng = fastrand::Rng::new(); let mut rng = fastrand::Rng::new();
for x in -stepmax..=stepmax { for x in -stepmax..=stepmax {
for y in -stepmax..=stepmax { for y in -stepmax..=stepmax {
@ -264,15 +279,21 @@ fn spawn_despawn_asteroids(
rng.seed(seed); rng.seed(seed);
let rand_s = rng.f32(); let rand_s = rng.f32();
let size: f32 = (rand_s + 1e-6).powf(-0.5) as f32; // -> between ~1 and 1000 let size_raw: f32 = (rand_s + 1e-4).powf(-0.5) as f32; // -> between ~1 and 100
let size_density = size_raw * density;
if rand_s > 0.7 { if size_density < 0.3 {
let dist = player_cell.as_dvec3().distance(origin.as_dvec3());
if dist > 4.0 {
continue; continue;
} }
if size_raw < 20.0 {
let dist = player_cell.as_dvec3().distance(origin.as_dvec3());
if dist > 6.0 {
continue;
}
dbg!(size_density, dist);
spawned_near += 1; spawned_near += 1;
} }
let size: f32 = ASTEROID_SIZE_FACTOR * size_density;
let rand_x = rng.f64(); let rand_x = rng.f64();
let rand_y = rng.f64(); let rand_y = rng.f64();
@ -306,7 +327,7 @@ fn spawn_despawn_asteroids(
entity_commands.insert(SceneBundle { entity_commands.insert(SceneBundle {
scene: asset_server.load(asset), scene: asset_server.load(asset),
transform: Transform { transform: Transform {
scale: Vec3::splat(ASTEROID_SIZE_FACTOR * size), scale: Vec3::splat(size),
..default() ..default()
}, },
..default() ..default()
@ -320,7 +341,7 @@ fn spawn_despawn_asteroids(
} }
} }
if spawned != 0 || despawned != 0 { if spawned != 0 || despawned != 0 {
log.notice(format!("spawned: {spawned} (near: {spawned_near}), despawned: {despawned}")); //log.notice(format!("spawned: {spawned} (near: {spawned_near}), despawned: {despawned}"));
} }
} }