Earth and moon eclipse
This commit is contained in:
1 parent
ff2ef10804
commit
85896b17a4
16 files changed
+575
-24
No files matched your search
@@ -27,8 +27,37 @@ fn resolved(args: &[&str]) -> std::process::Output {
|
||||
/// Renders `scene` on `adapter` to a 16-bit PNG and returns its pixels as DN (the
|
||||
/// file holds 12-bit DN shifted up by 4).
|
||||
fn render(scene: &str, adapter: &str) -> image::ImageBuffer<image::Rgb<u16>, Vec<u16>> {
|
||||
render_at(scene, adapter, "L0")
|
||||
}
|
||||
|
||||
/// A data directory whose Earth images are small and uniformly gray, for tests at
|
||||
/// lighting L1 that do not need Blue Marble: loading the real 16384 x 8192 images takes
|
||||
/// seconds in a debug build, and they are only there once fetched.
|
||||
fn gray_earth() -> PathBuf {
|
||||
static DIR: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new();
|
||||
DIR.get_or_init(|| {
|
||||
let dir = out_dir().join("gray-data");
|
||||
std::fs::create_dir_all(dir.join("earth")).unwrap();
|
||||
let image = image::RgbImage::from_pixel(64, 32, image::Rgb([128; 3]));
|
||||
for month in 1..=12 {
|
||||
image
|
||||
.save(dir.join(format!("earth/bmng-2004-{month:02}.jpg")))
|
||||
.unwrap();
|
||||
}
|
||||
dir
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
/// [`render`] at lighting tier `lighting`, with Earth's images from [`gray_earth`].
|
||||
fn render_at(
|
||||
scene: &str,
|
||||
adapter: &str,
|
||||
lighting: &str,
|
||||
) -> image::ImageBuffer<image::Rgb<u16>, Vec<u16>> {
|
||||
let data = gray_earth();
|
||||
let out = out_dir().join(format!(
|
||||
"{}-{adapter}.png",
|
||||
"{}-{lighting}-{adapter}.png",
|
||||
Path::new(scene).file_stem().unwrap().to_str().unwrap()
|
||||
));
|
||||
let preview = out.with_extension("preview.png");
|
||||
@@ -38,6 +67,10 @@ fn render(scene: &str, adapter: &str) -> image::ImageBuffer<image::Rgb<u16>, Vec
|
||||
scene,
|
||||
"--adapter",
|
||||
adapter,
|
||||
"--lighting",
|
||||
lighting,
|
||||
"--data",
|
||||
data.to_str().unwrap(),
|
||||
"--out",
|
||||
out.to_str().unwrap(),
|
||||
"--preview",
|
||||
@@ -92,6 +125,45 @@ fn epoch_scene_renders() {
|
||||
assert_eq!(frame.get_pixel(0, 0).0, [64; 3]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "astrokit")]
|
||||
#[test]
|
||||
fn lunar_eclipse_darkens_the_moon() {
|
||||
// Mid-totality: at L1 the whole Moon is in Earth's umbra and reads the bias. At L0
|
||||
// there are no eclipses on the bodies and it is a full Moon.
|
||||
let scene = "examples/scenes/lunar-eclipse.toml";
|
||||
let l0 = render_at(scene, "gpu", "L0");
|
||||
let l1 = render_at(scene, "gpu", "L1");
|
||||
assert!(
|
||||
l0.get_pixel(960, 540).0.iter().all(|&v| v > 150),
|
||||
"{:?}",
|
||||
l0.get_pixel(960, 540)
|
||||
);
|
||||
assert!(
|
||||
l1.pixels().all(|p| p.0 == [64; 3]),
|
||||
"every pixel at the bias"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "astrokit")]
|
||||
#[test]
|
||||
fn solar_eclipse_puts_the_umbra_at_greatest_eclipse() {
|
||||
// The camera looks straight down at the point of greatest eclipse from NASA's
|
||||
// bulletin (65.2 N 25.2 W, 17:46 UTC): at L1 it is in the Moon's umbra and reads the
|
||||
// bias, and the image corner, about 3500 km away in the penumbra, is brighter. At L0
|
||||
// the center is lit.
|
||||
let scene = "examples/scenes/solar-eclipse.toml";
|
||||
let l0 = render_at(scene, "gpu", "L0");
|
||||
let l1 = render_at(scene, "gpu", "L1");
|
||||
assert!(
|
||||
l0.get_pixel(960, 540).0.iter().all(|&v| v > 100),
|
||||
"{:?}",
|
||||
l0.get_pixel(960, 540)
|
||||
);
|
||||
assert_eq!(l1.get_pixel(960, 540).0, [64; 3]);
|
||||
let corner = l1.get_pixel(40, 1040).0;
|
||||
assert!(corner.iter().all(|&v| v > 70), "{corner:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_are_reported() {
|
||||
let missing = resolved(&["render", "--scene", "no/such.toml", "--preview", "x.png"]);
|
||||
|
||||
Reference in new issue
Block a user