use marss::rendering::atmosphere_scattering::*;
use marss::rendering::dust_rendering::*;
use marss::rendering::materials::*;
use marss::rendering::shaders::*;
use marss::rendering::sky::*;
#[test]
fn atmosphere_endpoint_mars() {
let a = AtmosphereEndpoint::mars();
assert!(a.planet_radius_m > 0.0);
assert!(a.atmosphere_height_m > 0.0);
assert!(a.sea_level_pressure_pa > 0.0);
assert!(a.sea_level_number_density_m3 > 0.0);
assert!(!a.species.is_empty());
}
#[test]
fn atmosphere_species_co2_dominant() {
let a = AtmosphereEndpoint::mars();
let co2 = a.species.iter().find(|s| s.symbol == "CO2").unwrap();
assert!(
co2.volume_fraction > 0.9,
"CO2 dominant: {}",
co2.volume_fraction
);
}
#[test]
fn atmosphere_species_molar_mass_positive() {
let a = AtmosphereEndpoint::mars();
for s in &a.species {
assert!(
s.molar_mass_kg_mol > 0.0,
"{} molar mass: {}",
s.name,
s.molar_mass_kg_mol
);
}
}
#[test]
fn rayleigh_density_decreases_with_alt() {
let a = AtmosphereEndpoint::mars();
let d0 = a.rayleigh_density(0.0);
let d10 = a.rayleigh_density(10_000.0);
assert!(d0 > d10, "Rayleigh decreases: {d0} > {d10}");
}
#[test]
fn dust_density_method() {
let a = AtmosphereEndpoint::mars();
let d = a.dust_density(0.0);
assert!(d >= 0.0, "Dust density >= 0: {d}");
}
#[test]
fn sky_color_rgb_range() {
let a = AtmosphereEndpoint::mars();
let c = a.sky_color(45.0);
assert!(c[0] >= 0.0 && c[0] <= 1.0);
assert!(c[1] >= 0.0 && c[1] <= 1.0);
assert!(c[2] >= 0.0 && c[2] <= 1.0);
}
#[test]
fn sky_color_butterscotch_tint() {
let a = AtmosphereEndpoint::mars();
let c = a.sky_color(45.0);
assert!(c[0] > c[2], "Mars sky red > blue: r={} b={}", c[0], c[2]);
}
#[test]
fn direct_transmission_decreases_with_airmass() {
let a = AtmosphereEndpoint::mars();
let t90 = a.direct_transmission(90.0);
let t30 = a.direct_transmission(30.0);
assert!(
t90 >= t30,
"Higher elev = more transmission: {t90} vs {t30}"
);
}
#[test]
fn direct_transmission_bounded() {
let a = AtmosphereEndpoint::mars();
let t = a.direct_transmission(45.0);
assert!((0.0..=1.0).contains(&t), "Transmission in [0,1]: {t}");
}
#[test]
fn sky_luminance_positive() {
let a = AtmosphereEndpoint::mars();
let l = a.sky_luminance(0.0, 0.7);
assert!(l >= 0.0, "Luminance >= 0: {l}");
}
#[test]
fn rayleigh_coefficients_positive() {
let a = AtmosphereEndpoint::mars();
assert!(a.rayleigh_coefficients_rgb[0] > 0.0);
assert!(a.rayleigh_coefficients_rgb[1] > 0.0);
assert!(a.rayleigh_coefficients_rgb[2] > 0.0);
}
#[test]
fn dust_background_od() {
let d = DustSystemEndpoint::mars_background();
assert!(d.optical_depth > 0.0 && d.optical_depth < 2.0);
}
#[test]
fn dust_global_storm_higher() {
let d = DustSystemEndpoint::mars_global_storm();
let bg = DustSystemEndpoint::mars_background();
assert!(d.optical_depth > bg.optical_depth);
}
#[test]
fn dust_global_storm_larger_particles() {
let bg = DustSystemEndpoint::mars_background();
let gs = DustSystemEndpoint::mars_global_storm();
assert!(gs.particle_effective_radius_um > bg.particle_effective_radius_um);
}
#[test]
fn density_at_altitude_decreases() {
let d = DustSystemEndpoint::mars_background();
let d0 = d.density_at_altitude(0.0);
let d10 = d.density_at_altitude(10_000.0);
assert!(d0 > d10, "Density decreases: {d0} vs {d10}");
}
#[test]
fn density_outside_bounds_zero() {
let d = DustSystemEndpoint::mars_background();
assert_eq!(d.density_at_altitude(-100.0), 0.0);
assert_eq!(d.density_at_altitude(100_000.0), 0.0);
}
#[test]
fn surface_solar_fraction_bounded() {
let d = DustSystemEndpoint::mars_background();
let f = d.surface_solar_fraction();
assert!(f > 0.0 && f <= 1.0, "Solar fraction: {f}");
}
#[test]
fn phase_function_forward_scatter() {
let d = DustSystemEndpoint::mars_background();
let pf = d.phase_function(1.0);
let pb = d.phase_function(-1.0);
assert!(pf > pb, "Forward > backward");
}
#[test]
fn effective_radius_positive() {
let d = DustSystemEndpoint::mars_background();
assert!(d.effective_radius_um() > 0.0);
}
#[test]
fn regolith_material_check() {
let m = regolith();
assert!(m.albedo[0] >= 0.0 && m.albedo[0] <= 1.0);
assert!(m.roughness > 0.0);
}
#[test]
fn bright_dust_brighter_than_dark_dune() {
let bright = bright_dust();
let dark = dark_dune();
let ba = (bright.albedo[0] + bright.albedo[1] + bright.albedo[2]) / 3.0;
let da = (dark.albedo[0] + dark.albedo[1] + dark.albedo[2]) / 3.0;
assert!(ba > da);
}
#[test]
fn basalt_material_check() {
let m = basalt();
assert!(m.roughness > 0.0);
assert!(m.metallic >= 0.0 && m.metallic <= 1.0);
}
#[test]
fn water_ice_high_albedo() {
let m = water_ice();
let avg = (m.albedo[0] + m.albedo[1] + m.albedo[2]) / 3.0;
assert!(avg > 0.4, "Ice albedo high: {avg}");
}
#[test]
fn co2_ice_smooth() {
let m = co2_ice();
assert!(m.roughness < 0.5, "Ice smooth: {}", m.roughness);
}
#[test]
fn sulfate_salt_check() {
let m = sulfate_salt();
assert!(m.albedo[0] >= 0.0);
}
#[test]
fn volcanic_summit_check() {
let m = volcanic_summit();
assert!(m.roughness > 0.0);
}
#[test]
fn terrain_shader_endpoint() {
let s = ShaderEndpoint::terrain();
assert!(!s.name.is_empty());
assert!(!s.uniforms.is_empty());
assert!(s.uniforms.iter().any(|u| u.name == "u_sun_direction"));
assert!(s.uniforms.iter().any(|u| u.name == "u_dust_optical_depth"));
}
#[test]
fn atmosphere_shader_endpoint() {
let s = ShaderEndpoint::atmosphere();
assert!(!s.name.is_empty());
assert!(s.uniforms.iter().any(|u| u.name == "u_rayleigh_coeff"));
assert!(s.uniforms.iter().any(|u| u.name == "u_mie_g"));
}
#[test]
fn dust_storm_shader_endpoint() {
let s = ShaderEndpoint::dust_storm();
assert!(!s.uniforms.is_empty());
assert!(s.uniforms.iter().any(|u| u.name == "u_dust_optical_depth"));
assert!(s.uniforms.iter().any(|u| u.name == "u_storm_intensity"));
}
#[test]
fn shader_uniform_value_mutation() {
let mut s = ShaderEndpoint::terrain();
s.uniforms[0].value = UniformValue::Vec3([1.0, 0.0, 0.0]);
match &s.uniforms[0].value {
UniformValue::Vec3(v) => assert_eq!(v[0], 1.0),
_ => panic!("Expected Vec3"),
}
}
#[test]
fn sky_state_zenith_color() {
let s = SkyState::new(45.0, 0.3);
let c = s.zenith_color();
assert!(c[0] >= 0.0 && c[0] <= 1.0);
}
#[test]
fn sky_state_sunset_color() {
let s = SkyState::new(5.0, 0.3);
let c = s.sunset_color();
assert!(c[2] > c[0], "Mars sunset blue > red");
}
#[test]
fn sky_state_horizon_glow() {
let s = SkyState::new(2.0, 0.5);
let g = s.horizon_glow();
assert!(g > 0.0, "Horizon glow > 0 near sunset");
}
#[test]
fn sky_state_night() {
let s = SkyState::new(-20.0, 0.3);
let c = s.zenith_color();
let brightness = c[0] + c[1] + c[2];
assert!(brightness < 0.5, "Night sky dim: {brightness}");
}