#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; 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 { 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; let color = vec3(0.3, 0.3, 0.3); 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 *= ring_density2(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 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); }