From 83b44d4dbc27dae349aa5422d687b6a707e58b31 Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 00:47:03 +0200 Subject: [PATCH 1/7] WIP ring effect --- Cargo.lock | 116 +++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- assets/shaders/testshader.wgsl | 22 +++++++ src/world.rs | 34 ++++++++++ 4 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 assets/shaders/testshader.wgsl diff --git a/Cargo.lock b/Cargo.lock index 332390e..4b20662 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,6 +349,7 @@ dependencies = [ "futures-io", "futures-lite", "js-sys", + "notify-debouncer-full", "parking_lot", "ron", "serde", @@ -1716,6 +1717,27 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "file-id" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6584280525fb2059cba3db2c04abf947a1a29a45ddae89f3870f8281704fafc9" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1759,6 +1781,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "futures-core" version = "0.3.30" @@ -2062,6 +2093,26 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "itertools" version = "0.12.1" @@ -2140,6 +2191,26 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + [[package]] name = "ktx2" version = "0.3.0" @@ -2311,6 +2382,18 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "naga" version = "0.19.2" @@ -2426,6 +2509,39 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.4.2", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "notify-debouncer-full" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f5dab59c348b9b50cf7f261960a20e389feb2713636399cd9082cd4b536154" +dependencies = [ + "crossbeam-channel", + "file-id", + "log", + "notify", + "parking_lot", + "walkdir", +] + [[package]] name = "ntapi" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 2d21711..9b3d4db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ rust-version = "1.76.0" [dependencies] regex = "1" -bevy = { version = "0.13.1", default-features = false, features = ["jpeg", "bevy_asset", "bevy_audio", "bevy_scene", "bevy_winit", "bevy_core_pipeline", "bevy_pbr", "bevy_gltf", "bevy_render", "bevy_text", "bevy_ui", "multi-threaded", "png", "vorbis", "x11", "tonemapping_luts"]} +bevy = { version = "0.13.1", default-features = false, features = ["jpeg", "bevy_asset", "bevy_audio", "bevy_scene", "bevy_winit", "bevy_core_pipeline", "bevy_pbr", "bevy_gltf", "bevy_render", "bevy_text", "bevy_ui", "file_watcher", "multi-threaded", "png", "vorbis", "x11", "tonemapping_luts"]} bevy_xpbd_3d = { version = "0.4", default-features = false, features = ["3d", "f32", "parry-f32", "parallel", "async-collider"] } bevy_embedded_assets = "0.10.2" diff --git a/assets/shaders/testshader.wgsl b/assets/shaders/testshader.wgsl new file mode 100644 index 0000000..6ded205 --- /dev/null +++ b/assets/shaders/testshader.wgsl @@ -0,0 +1,22 @@ +#import bevy_pbr::{ + mesh_view_bindings::globals, + forward_io::VertexOutput, +} + +@fragment +fn fragment(in: VertexOutput) -> @location(0) vec4 { + let speed = 3.0; + let t_1 = sin(globals.time * speed) * 0.5 + 0.5; + let t_2 = cos(globals.time * speed); + + let distance_to_center = distance(in.uv, vec2(0.5)) * 1.4; + + let red = vec3(0.627955, 0.224863, 0.125846); + let green = vec3(0.86644, -0.233887, 0.179498); + let blue = vec3(0.701674, 0.274566, -0.169156); + let white = vec3(1.0, 0.0, 0.0); + let pos = vec3(in.position[0], in.position[1], in.position[2]); + let mixed = mix(pos, mix(green, white, t_2), distance_to_center); + + return vec4(mixed, 1.0); +} diff --git a/src/world.rs b/src/world.rs index d5c96e6..fdcdc03 100644 --- a/src/world.rs +++ b/src/world.rs @@ -4,6 +4,7 @@ use bevy::prelude::*; //use bevy::asset::LoadState; //use bevy::render::render_resource::{TextureViewDescriptor, TextureViewDimension}; use bevy::pbr::CascadeShadowConfigBuilder; +use bevy::render::render_resource::{AsBindGroup, ShaderRef}; use bevy_xpbd_3d::prelude::*; use std::f32::consts::PI; @@ -39,11 +40,21 @@ impl Plugin for WorldPlugin { //app.add_systems(Update, asset_loaded.after(load_cubemap_asset)); //app.add_systems(Update, swap_world_on_ar_toggle); app.add_plugins(PhysicsPlugins::default()); + app.add_plugins(MaterialPlugin::::default()); //app.add_plugins(PhysicsDebugPlugin::default()); app.insert_resource(Gravity(Vec3::splat(0.0))); } } +#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] +pub struct CustomMaterial {} + +impl Material for CustomMaterial { + fn fragment_shader() -> ShaderRef { + "shaders/testshader.wgsl".into() + } +} + #[derive(Component)] pub struct Star; @@ -68,6 +79,7 @@ pub fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, + mut materials_custom: ResMut>, asset_server: Res, ) { // let cubemap_handle = asset_server.load(ASSET_CUBEMAP); @@ -162,6 +174,28 @@ pub fn setup( } info!("Generated {starcount} stars"); + // Add shaded ring + let max = 20; + for i in 0..max { + let f = i as f32; + let maxf = max as f32; + let ringmesh = Mesh::from(Cylinder::new(400000.0 + f * 10000.0, 5000.0 - 150.0 * f)); + let clr = 0.4 + (f/maxf).clamp(0.0,0.6); + commands.spawn(MaterialMeshBundle { + mesh: meshes.add(ringmesh), + transform: Transform::from_xyz(300000.0, 0.0, 500000.0), + //material: materials_custom.add(CustomMaterial {}), + material: materials.add(StandardMaterial { + base_color: Color::rgba(clr, clr, clr, 0.0001), + unlit: true, + cull_mode: None, + alpha_mode: AlphaMode::Blend, + ..default() + }), + ..default() + }); + } + // Add Light from the Sun commands.spawn(DirectionalLightBundle { directional_light: DirectionalLight { From 2121642b92d24a94dc3de65a6c72d952a362bd5e Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 02:05:38 +0200 Subject: [PATCH 2/7] first attempt at jovian ring with shader --- assets/shaders/jupiters_rings.wgsl | 33 +++++++++++++ assets/shaders/testshader.wgsl | 22 --------- src/world.rs | 76 ++++++++++++++++++++---------- 3 files changed, 84 insertions(+), 47 deletions(-) create mode 100644 assets/shaders/jupiters_rings.wgsl delete mode 100644 assets/shaders/testshader.wgsl diff --git a/assets/shaders/jupiters_rings.wgsl b/assets/shaders/jupiters_rings.wgsl new file mode 100644 index 0000000..6f4b573 --- /dev/null +++ b/assets/shaders/jupiters_rings.wgsl @@ -0,0 +1,33 @@ +#import bevy_pbr::{ + mesh_view_bindings::globals, + forward_io::VertexOutput, +} + +@group(2) @binding(0) var ring_radius: f32; +@group(2) @binding(1) var jupiter_radius: f32; + +@fragment +fn fragment(in: VertexOutput) -> @location(0) vec4 { + let jupiter_percent = jupiter_radius / ring_radius; + let color = vec3(0.3, 0.3, 0.3); + var alpha = 0.01; + let r = distance(in.uv, vec2(0.5)); + + alpha *= (sin(11*r / 0.71 * 3.1415) + 1) / 2; + alpha *= (cos(r / 0.72 * 3.1415) + 1) / 2; + + if in.uv[0] < 0.5 { + let dist = (0.5 - in.uv[0]) * 2.0; // 0.0=jupiter's center, 1.0=edge of the ring + let side_dist = abs(in.uv[1] - 0.5); + + let cutoff = 0.5 * jupiter_percent * cos(dist); + if side_dist < cutoff { + return vec4(color, 0.0); + } + let fuzzy_boundary = 0.01; + if side_dist < cutoff + fuzzy_boundary { + return vec4(color, alpha * (side_dist - cutoff) / fuzzy_boundary); + } + } + return vec4(color, alpha); +} diff --git a/assets/shaders/testshader.wgsl b/assets/shaders/testshader.wgsl deleted file mode 100644 index 6ded205..0000000 --- a/assets/shaders/testshader.wgsl +++ /dev/null @@ -1,22 +0,0 @@ -#import bevy_pbr::{ - mesh_view_bindings::globals, - forward_io::VertexOutput, -} - -@fragment -fn fragment(in: VertexOutput) -> @location(0) vec4 { - let speed = 3.0; - let t_1 = sin(globals.time * speed) * 0.5 + 0.5; - let t_2 = cos(globals.time * speed); - - let distance_to_center = distance(in.uv, vec2(0.5)) * 1.4; - - let red = vec3(0.627955, 0.224863, 0.125846); - let green = vec3(0.86644, -0.233887, 0.179498); - let blue = vec3(0.701674, 0.274566, -0.169156); - let white = vec3(1.0, 0.0, 0.0); - let pos = vec3(in.position[0], in.position[1], in.position[2]); - let mixed = mix(pos, mix(green, white, t_2), distance_to_center); - - return vec4(mixed, 1.0); -} diff --git a/src/world.rs b/src/world.rs index fdcdc03..900c26d 100644 --- a/src/world.rs +++ b/src/world.rs @@ -40,18 +40,27 @@ impl Plugin for WorldPlugin { //app.add_systems(Update, asset_loaded.after(load_cubemap_asset)); //app.add_systems(Update, swap_world_on_ar_toggle); app.add_plugins(PhysicsPlugins::default()); - app.add_plugins(MaterialPlugin::::default()); + app.add_plugins(MaterialPlugin::::default()); //app.add_plugins(PhysicsDebugPlugin::default()); app.insert_resource(Gravity(Vec3::splat(0.0))); } } #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] -pub struct CustomMaterial {} +pub struct RingMaterial { + alpha_mode: AlphaMode, + #[uniform(0)] + ring_radius: f32, + #[uniform(1)] + jupiter_radius: f32, +} -impl Material for CustomMaterial { +impl Material for RingMaterial { fn fragment_shader() -> ShaderRef { - "shaders/testshader.wgsl".into() + "shaders/jupiters_rings.wgsl".into() + } + fn alpha_mode(&self) -> AlphaMode { + self.alpha_mode } } @@ -79,7 +88,7 @@ pub fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, - mut materials_custom: ResMut>, + mut materials_custom: ResMut>, asset_server: Res, ) { // let cubemap_handle = asset_server.load(ASSET_CUBEMAP); @@ -175,26 +184,43 @@ pub fn setup( info!("Generated {starcount} stars"); // Add shaded ring - let max = 20; - for i in 0..max { - let f = i as f32; - let maxf = max as f32; - let ringmesh = Mesh::from(Cylinder::new(400000.0 + f * 10000.0, 5000.0 - 150.0 * f)); - let clr = 0.4 + (f/maxf).clamp(0.0,0.6); - commands.spawn(MaterialMeshBundle { - mesh: meshes.add(ringmesh), - transform: Transform::from_xyz(300000.0, 0.0, 500000.0), - //material: materials_custom.add(CustomMaterial {}), - material: materials.add(StandardMaterial { - base_color: Color::rgba(clr, clr, clr, 0.0001), - unlit: true, - cull_mode: None, - alpha_mode: AlphaMode::Blend, - ..default() - }), - ..default() - }); - } + let ring_radius = 900000.0; + let jupiter_radius = 200000.0; + commands.spawn(MaterialMeshBundle { + mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))), + transform: Transform::from_xyz(300000.0, -4000.0, 500000.0) + .with_rotation(Quat::from_rotation_z(PI*0.05)) + , + //transform: Transform::from_xyz(300000.0, 0.0, 500000.0)), + material: materials_custom.add(RingMaterial { + alpha_mode: AlphaMode::Blend, + ring_radius: ring_radius, + jupiter_radius: jupiter_radius, + }), + ..default() + }); + //let max = 20; + //for i in 0..max { + // let f = i as f32; + // let maxf = max as f32; + // let ringmesh = Mesh::from(Cylinder::new(400000.0 + f * 10000.0, 5000.0 - 150.0 * f)); + // let clr = 0.4 + (f/maxf).clamp(0.0,0.6); + // commands.spawn(MaterialMeshBundle { + // mesh: meshes.add(ringmesh), + // transform: Transform::from_xyz(300000.0, 0.0, 500000.0), + // material: materials_custom.add(RingMaterial { + // alpha_mode: AlphaMode::Blend, + // }), + // material: materials.add(StandardMaterial { + // base_color: Color::rgba(clr, clr, clr, 0.0001), + // unlit: true, + // cull_mode: None, + // alpha_mode: AlphaMode::Blend, + // ..default() + // }), + // ..default() + // }); + //} // Add Light from the Sun commands.spawn(DirectionalLightBundle { From 394390a4d6ffa1d8878d863b3c559416c56df4e5 Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 03:12:59 +0200 Subject: [PATCH 3/7] more realistic ring density function --- assets/shaders/jupiters_rings.wgsl | 148 ++++++++++++++++++++++++++++- src/defs.txt | 2 +- src/world.rs | 2 +- 3 files changed, 146 insertions(+), 6 deletions(-) diff --git a/assets/shaders/jupiters_rings.wgsl b/assets/shaders/jupiters_rings.wgsl index 6f4b573..be61819 100644 --- a/assets/shaders/jupiters_rings.wgsl +++ b/assets/shaders/jupiters_rings.wgsl @@ -6,15 +6,155 @@ @group(2) @binding(0) var ring_radius: f32; @group(2) @binding(1) var jupiter_radius: f32; +const jupiter_radius_Mm: f32 = 71.492; + +//fn ring_density(r: f32) -> f32 { +// // r is in terms of megameters. +//// if r < 92 { +//// return 0.0; +//// } +//// if r > 226 { +//// return 0.0; +//// } +// +// let B0: f32 = 1.0; +// let d0: f32 = 71492.0; +// let lambda: f32 = 5000.0; +// let alpha: f32 = 0.1; +// let beta: f32 = 0.001; +// let dist = r * 400; +// +// let brightness: f32 = B0 * exp(-(dist - d0) / lambda) * (1.0 + alpha * sin(beta * (dist - d0))); +// return brightness * 1; +//} + +//fn ring_density(r: f32) -> f32 { +// if r < jupiter_radius_Mm { +// return 0.0; +// } +// if r > jupiter_radius_Mm * 3 { +// return 0.0; +// } +// let radius = (r - jupiter_radius_Mm) / (jupiter_radius_Mm * 2) + 1; +// // Constants representing the approximate normalized start, peak, and end radii of the rings +// let halo_start: f32 = 1.1; +// let halo_peak: f32 = 1.2; +// let halo_end: f32 = 1.3; +// +// let main_start: f32 = 1.4; +// let main_peak: f32 = 1.5; +// let main_end: f32 = 1.6; +// +// let gossamer_start: f32 = 1.7; +// let gossamer_peak: f32 = 1.8; +// let gossamer_end: f32 = 1.9; +// +// // Piecewise linear function for density approximation +// if (radius >= halo_start && radius < halo_peak) { +// return 1.0; +// //return (radius - halo_start) / (halo_peak - halo_start); +// } else if (radius >= halo_peak && radius <= halo_end) { +// return 1.0 - (radius - halo_peak) / (halo_end - halo_peak); +// } else if (radius >= main_start && radius < main_peak) { +// return (radius - main_start) / (main_peak - main_start); +// } else if (radius >= main_peak && radius <= main_end) { +// return 1.0 - (radius - main_peak) / (main_end - main_peak); +// } else if (radius >= gossamer_start && radius < gossamer_peak) { +// return (radius - gossamer_start) / (gossamer_peak - gossamer_start); +// } else if (radius >= gossamer_peak && radius <= gossamer_end) { +// return 1.0 - (radius - gossamer_peak) / (gossamer_end - gossamer_peak); +// } +// +// return 0.0; // Outside of rings, density is 0 +//} + +//fn ring_density(radius: f32) -> f32 { +// // Define key radii for Jupiter's rings and gaps +// let inner_radius: f32 = 1.806e5; // Inner boundary of the Halo ring +// let halo_main_gap: f32 = 1.22e5; // Gap between Halo and Main rings +// let main_amalthea_gap: f32 = 1.8e5; // Gap between Main and Amalthea Gossamer ring +// let amalthea_thebe_gap: f32 = 2.24e5; // Gap between Amalthea and Thebe Gossamer rings +// let outer_radius: f32 = 2.2e5; // Outer boundary of Thebe Gossamer ring +// let metis_notch_inner: f32 = 1.28e5; // Inner boundary of Metis notch +// let metis_notch_outer: f32 = 1.29e5; // Outer boundary of Metis notch +// +// // Density function +// if radius > outer_radius { +// return 0.0; // Beyond rings, density is zero +// } else if radius > metis_notch_inner && radius < metis_notch_outer { +// return 0.2; // Notch at the orbit of Metis +// } else if radius > halo_main_gap && radius < main_amalthea_gap { +// return 1.0; // Highest density in Main ring +// } else if radius > amalthea_thebe_gap { +// return 0.5; // Lower density in Thebe Gossamer ring +// } else { +// return 0.75; // Moderate density in other areas +// } +//} + +// Smooth step function for edge smoothing +fn smooth_edge(start: f32, end: f32, value: f32, smooth_factor: f32) -> f32 { + var x = ((value - start) / (end - start)); + if x < 0 { + return 0.0; + } + if x > 1 { + return 1.0; + } + return pow(x, smooth_factor) * (3.0 - 2.0 * x); +} +fn ring_density(radius: f32) -> f32 { + 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.4; + let main_brightness: f32 = 1.0; + let almathea_brightness: f32 = 0.3; + let thebe_brightness: f32 = 0.2; + + let smooth_factor: f32 = 2.0; // Smooth edges + + if radius < halo_inner || radius > thebe_outer { + return 0.0; + } else if radius >= halo_inner && radius <= halo_outer { + return halo_brightness * smooth_edge(halo_inner, halo_outer, radius, smooth_factor); + } else if radius >= main_inner && radius <= main_outer { + var metis_notch_effect = 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, smooth_factor)); + } + return main_brightness * metis_notch_effect * smooth_edge(main_inner, main_outer, radius, smooth_factor); + } else if radius >= amalthea_inner && radius <= amalthea_outer { + return almathea_brightness * smooth_edge(amalthea_inner, amalthea_outer, radius, smooth_factor); + } else if radius >= thebe_inner && radius <= thebe_outer { + return thebe_brightness * smooth_edge(thebe_inner, thebe_outer, radius, smooth_factor); + } + return 0.0; +} + @fragment fn fragment(in: VertexOutput) -> @location(0) vec4 { let jupiter_percent = jupiter_radius / ring_radius; let color = vec3(0.3, 0.3, 0.3); - var alpha = 0.01; - let r = distance(in.uv, vec2(0.5)); + var alpha = 0.04; + let r_uv = 2 * distance(in.uv, vec2(0.5)); + let r = r_uv * ring_radius / jupiter_radius * jupiter_radius_Mm; - alpha *= (sin(11*r / 0.71 * 3.1415) + 1) / 2; - alpha *= (cos(r / 0.72 * 3.1415) + 1) / 2; + alpha *= ring_density(r); + if alpha <= 0.0 { + return vec4(color, alpha); + } + + //alpha *= (sin(11*r / 0.71 * 3.1415) + 1) / 2; + //alpha *= (cos(r / 0.72 * 3.1415) + 1) / 2; if in.uv[0] < 0.5 { let dist = (0.5 - in.uv[0]) * 2.0; // 0.0=jupiter's center, 1.0=edge of the ring diff --git a/src/defs.txt b/src/defs.txt index b61f6f8..a437be0 100644 --- a/src/defs.txt +++ b/src/defs.txt @@ -1,4 +1,4 @@ -actor 0 0 0 suit +actor -800000 800000 0 suit player yes mass 200.0 scale 1 diff --git a/src/world.rs b/src/world.rs index 900c26d..b2e70a8 100644 --- a/src/world.rs +++ b/src/world.rs @@ -184,7 +184,7 @@ pub fn setup( info!("Generated {starcount} stars"); // Add shaded ring - let ring_radius = 900000.0; + let ring_radius = 640000.0; let jupiter_radius = 200000.0; commands.spawn(MaterialMeshBundle { mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))), From 3c7077f4484d78292a74024148c3ff03eb35da0a Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 03:45:32 +0200 Subject: [PATCH 4/7] even nicer rings --- assets/shaders/jupiters_rings.wgsl | 49 +++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/assets/shaders/jupiters_rings.wgsl b/assets/shaders/jupiters_rings.wgsl index be61819..95fab9f 100644 --- a/assets/shaders/jupiters_rings.wgsl +++ b/assets/shaders/jupiters_rings.wgsl @@ -140,6 +140,53 @@ fn ring_density(radius: f32) -> f32 { return 0.0; } +fn smooth_edge2(start: f32, end: f32, value: f32) -> f32 { + var x: f32 = (value - start) / (end - start); + return 4 * x * x * (1 - x * x); +} + +fn ring_density2(radius: f32) -> f32 { + 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.3; + let main_brightness: f32 = 1.0; + let almathea_brightness: f32 = 0.2; + let thebe_brightness: f32 = 0.2; + + 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; + + if (radius >= halo_inner && radius <= halo_outer) { + density = halo_brightness * smooth_edge2(halo_inner, halo_outer, radius); + } else if (radius >= main_inner && radius <= main_outer) { + var 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_edge2(metis_notch_center - metis_notch_width * 0.5, metis_notch_center + metis_notch_width * 0.5, radius)); + } + density = main_brightness * metis_notch_effect * smooth_edge2(main_inner, main_outer, radius); + } else { + if (radius >= amalthea_inner && radius <= amalthea_outer) { + density = almathea_brightness * smooth_edge2(amalthea_inner, amalthea_outer, radius); + } + if (radius >= thebe_inner && radius <= thebe_outer) { + density += thebe_brightness * smooth_edge2(thebe_inner, thebe_outer, radius); + } + } + + return density; +} + @fragment fn fragment(in: VertexOutput) -> @location(0) vec4 { let jupiter_percent = jupiter_radius / ring_radius; @@ -148,7 +195,7 @@ fn fragment(in: VertexOutput) -> @location(0) vec4 { let r_uv = 2 * distance(in.uv, vec2(0.5)); let r = r_uv * ring_radius / jupiter_radius * jupiter_radius_Mm; - alpha *= ring_density(r); + alpha *= ring_density2(r); if alpha <= 0.0 { return vec4(color, alpha); } From 0e1761855b197228cf2235490b582f899ccd5689 Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 03:58:32 +0200 Subject: [PATCH 5/7] cleanup --- assets/shaders/jupiters_rings.wgsl | 147 ++--------------------------- src/defs.txt | 2 +- src/world.rs | 4 +- 3 files changed, 9 insertions(+), 144 deletions(-) diff --git a/assets/shaders/jupiters_rings.wgsl b/assets/shaders/jupiters_rings.wgsl index 95fab9f..b94147d 100644 --- a/assets/shaders/jupiters_rings.wgsl +++ b/assets/shaders/jupiters_rings.wgsl @@ -8,139 +8,7 @@ const jupiter_radius_Mm: f32 = 71.492; -//fn ring_density(r: f32) -> f32 { -// // r is in terms of megameters. -//// if r < 92 { -//// return 0.0; -//// } -//// if r > 226 { -//// return 0.0; -//// } -// -// let B0: f32 = 1.0; -// let d0: f32 = 71492.0; -// let lambda: f32 = 5000.0; -// let alpha: f32 = 0.1; -// let beta: f32 = 0.001; -// let dist = r * 400; -// -// let brightness: f32 = B0 * exp(-(dist - d0) / lambda) * (1.0 + alpha * sin(beta * (dist - d0))); -// return brightness * 1; -//} - -//fn ring_density(r: f32) -> f32 { -// if r < jupiter_radius_Mm { -// return 0.0; -// } -// if r > jupiter_radius_Mm * 3 { -// return 0.0; -// } -// let radius = (r - jupiter_radius_Mm) / (jupiter_radius_Mm * 2) + 1; -// // Constants representing the approximate normalized start, peak, and end radii of the rings -// let halo_start: f32 = 1.1; -// let halo_peak: f32 = 1.2; -// let halo_end: f32 = 1.3; -// -// let main_start: f32 = 1.4; -// let main_peak: f32 = 1.5; -// let main_end: f32 = 1.6; -// -// let gossamer_start: f32 = 1.7; -// let gossamer_peak: f32 = 1.8; -// let gossamer_end: f32 = 1.9; -// -// // Piecewise linear function for density approximation -// if (radius >= halo_start && radius < halo_peak) { -// return 1.0; -// //return (radius - halo_start) / (halo_peak - halo_start); -// } else if (radius >= halo_peak && radius <= halo_end) { -// return 1.0 - (radius - halo_peak) / (halo_end - halo_peak); -// } else if (radius >= main_start && radius < main_peak) { -// return (radius - main_start) / (main_peak - main_start); -// } else if (radius >= main_peak && radius <= main_end) { -// return 1.0 - (radius - main_peak) / (main_end - main_peak); -// } else if (radius >= gossamer_start && radius < gossamer_peak) { -// return (radius - gossamer_start) / (gossamer_peak - gossamer_start); -// } else if (radius >= gossamer_peak && radius <= gossamer_end) { -// return 1.0 - (radius - gossamer_peak) / (gossamer_end - gossamer_peak); -// } -// -// return 0.0; // Outside of rings, density is 0 -//} - -//fn ring_density(radius: f32) -> f32 { -// // Define key radii for Jupiter's rings and gaps -// let inner_radius: f32 = 1.806e5; // Inner boundary of the Halo ring -// let halo_main_gap: f32 = 1.22e5; // Gap between Halo and Main rings -// let main_amalthea_gap: f32 = 1.8e5; // Gap between Main and Amalthea Gossamer ring -// let amalthea_thebe_gap: f32 = 2.24e5; // Gap between Amalthea and Thebe Gossamer rings -// let outer_radius: f32 = 2.2e5; // Outer boundary of Thebe Gossamer ring -// let metis_notch_inner: f32 = 1.28e5; // Inner boundary of Metis notch -// let metis_notch_outer: f32 = 1.29e5; // Outer boundary of Metis notch -// -// // Density function -// if radius > outer_radius { -// return 0.0; // Beyond rings, density is zero -// } else if radius > metis_notch_inner && radius < metis_notch_outer { -// return 0.2; // Notch at the orbit of Metis -// } else if radius > halo_main_gap && radius < main_amalthea_gap { -// return 1.0; // Highest density in Main ring -// } else if radius > amalthea_thebe_gap { -// return 0.5; // Lower density in Thebe Gossamer ring -// } else { -// return 0.75; // Moderate density in other areas -// } -//} - -// Smooth step function for edge smoothing -fn smooth_edge(start: f32, end: f32, value: f32, smooth_factor: f32) -> f32 { - var x = ((value - start) / (end - start)); - if x < 0 { - return 0.0; - } - if x > 1 { - return 1.0; - } - return pow(x, smooth_factor) * (3.0 - 2.0 * x); -} -fn ring_density(radius: f32) -> f32 { - 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.4; - let main_brightness: f32 = 1.0; - let almathea_brightness: f32 = 0.3; - let thebe_brightness: f32 = 0.2; - - let smooth_factor: f32 = 2.0; // Smooth edges - - if radius < halo_inner || radius > thebe_outer { - return 0.0; - } else if radius >= halo_inner && radius <= halo_outer { - return halo_brightness * smooth_edge(halo_inner, halo_outer, radius, smooth_factor); - } else if radius >= main_inner && radius <= main_outer { - var metis_notch_effect = 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, smooth_factor)); - } - return main_brightness * metis_notch_effect * smooth_edge(main_inner, main_outer, radius, smooth_factor); - } else if radius >= amalthea_inner && radius <= amalthea_outer { - return almathea_brightness * smooth_edge(amalthea_inner, amalthea_outer, radius, smooth_factor); - } else if radius >= thebe_inner && radius <= thebe_outer { - return thebe_brightness * smooth_edge(thebe_inner, thebe_outer, radius, smooth_factor); - } - return 0.0; -} - -fn smooth_edge2(start: f32, end: f32, value: f32) -> f32 { +fn smooth_edge(start: f32, end: f32, value: f32) -> f32 { var x: f32 = (value - start) / (end - start); return 4 * x * x * (1 - x * x); } @@ -168,19 +36,19 @@ fn ring_density2(radius: f32) -> f32 { var density: f32 = 0.0; if (radius >= halo_inner && radius <= halo_outer) { - density = halo_brightness * smooth_edge2(halo_inner, halo_outer, radius); + density = halo_brightness * smooth_edge(halo_inner, halo_outer, radius); } else if (radius >= main_inner && radius <= main_outer) { var 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_edge2(metis_notch_center - metis_notch_width * 0.5, metis_notch_center + metis_notch_width * 0.5, radius)); + 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_edge2(main_inner, main_outer, 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_edge2(amalthea_inner, amalthea_outer, radius); + density = almathea_brightness * smooth_edge(amalthea_inner, amalthea_outer, radius); } if (radius >= thebe_inner && radius <= thebe_outer) { - density += thebe_brightness * smooth_edge2(thebe_inner, thebe_outer, radius); + density += thebe_brightness * smooth_edge(thebe_inner, thebe_outer, radius); } } @@ -200,9 +68,6 @@ fn fragment(in: VertexOutput) -> @location(0) vec4 { return vec4(color, alpha); } - //alpha *= (sin(11*r / 0.71 * 3.1415) + 1) / 2; - //alpha *= (cos(r / 0.72 * 3.1415) + 1) / 2; - if in.uv[0] < 0.5 { let dist = (0.5 - in.uv[0]) * 2.0; // 0.0=jupiter's center, 1.0=edge of the ring let side_dist = abs(in.uv[1] - 0.5); diff --git a/src/defs.txt b/src/defs.txt index a437be0..b61f6f8 100644 --- a/src/defs.txt +++ b/src/defs.txt @@ -1,4 +1,4 @@ -actor -800000 800000 0 suit +actor 0 0 0 suit player yes mass 200.0 scale 1 diff --git a/src/world.rs b/src/world.rs index b2e70a8..7286e8b 100644 --- a/src/world.rs +++ b/src/world.rs @@ -188,8 +188,8 @@ pub fn setup( let jupiter_radius = 200000.0; commands.spawn(MaterialMeshBundle { mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))), - transform: Transform::from_xyz(300000.0, -4000.0, 500000.0) - .with_rotation(Quat::from_rotation_z(PI*0.05)) + transform: Transform::from_xyz(300000.0, -1000.0, 500000.0) + .with_rotation(Quat::from_rotation_z(1f32.to_radians())) , //transform: Transform::from_xyz(300000.0, 0.0, 500000.0)), material: materials_custom.add(RingMaterial { From 123038b864c48972428356825076c57eb5af95ea Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 03:58:36 +0200 Subject: [PATCH 6/7] dim rings a bit --- assets/shaders/jupiters_rings.wgsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/shaders/jupiters_rings.wgsl b/assets/shaders/jupiters_rings.wgsl index b94147d..01080e6 100644 --- a/assets/shaders/jupiters_rings.wgsl +++ b/assets/shaders/jupiters_rings.wgsl @@ -59,7 +59,7 @@ fn ring_density2(radius: f32) -> f32 { fn fragment(in: VertexOutput) -> @location(0) vec4 { let jupiter_percent = jupiter_radius / ring_radius; let color = vec3(0.3, 0.3, 0.3); - var alpha = 0.04; + var alpha = 0.02; let r_uv = 2 * distance(in.uv, vec2(0.5)); let r = r_uv * ring_radius / jupiter_radius * jupiter_radius_Mm; From ff363d03efb9abec00e540d1e2d846d59270980a Mon Sep 17 00:00:00 2001 From: hut Date: Mon, 1 Apr 2024 04:00:57 +0200 Subject: [PATCH 7/7] cleanup --- assets/shaders/jupiters_rings.wgsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/shaders/jupiters_rings.wgsl b/assets/shaders/jupiters_rings.wgsl index 01080e6..50d18fd 100644 --- a/assets/shaders/jupiters_rings.wgsl +++ b/assets/shaders/jupiters_rings.wgsl @@ -13,7 +13,7 @@ fn smooth_edge(start: f32, end: f32, value: f32) -> f32 { return 4 * x * x * (1 - x * x); } -fn ring_density2(radius: f32) -> f32 { +fn ring_density(radius: f32) -> f32 { let halo_inner: f32 = 92.0; let halo_outer: f32 = 122.5; let main_inner: f32 = 122.5; @@ -63,7 +63,7 @@ fn fragment(in: VertexOutput) -> @location(0) vec4 { let r_uv = 2 * distance(in.uv, vec2(0.5)); let r = r_uv * ring_radius / jupiter_radius * jupiter_radius_Mm; - alpha *= ring_density2(r); + alpha *= ring_density(r); if alpha <= 0.0 { return vec4(color, alpha); }