Saturation and blooming

This commit is contained in:
connor committed 2026-10-16 16:31:53 -04:00
1 parent 3d0b129582
commit 7e1b64c186
17 files changed
+694 -71

No files matched your search

+1 -1
View File
@@ -60,7 +60,7 @@ struct RenderArgs {
/// Camera fidelity tier: C0, or C1 (adds pixels that collect light over their area,
/// for graded edges and continuous thin parts, lens distortion, lens blur, and the
/// Sun, Moon and Earth where light time and aberration make them appear, detector
/// noise and fixed pattern, and at lighting L1 stars).
/// noise, fixed pattern and blooming, and at lighting L1 stars).
#[arg(long, default_value = "C0")]
camera: CameraTier,
/// From camera C1: render each pixel as N x N finer ones (1 to 4; default 2), which
+23 -3
View File
@@ -11,8 +11,8 @@ use resolved::bodies::Appearance;
use resolved::nalgebra::{Quaternion, UnitQuaternion, Vector2, Vector3};
use resolved::scene::Velocities;
use resolved::{
BrownConrady, CameraConfig, LoadOptions, Material, Mesh, ModelId, Pose, Psf, Renderer, Scene,
Spectrum, Target,
Blooming, BrownConrady, CameraConfig, LoadOptions, Material, Mesh, ModelId, Pose, Psf,
Renderer, Scene, Spectrum, Target,
};
use serde::Deserialize;
@@ -82,6 +82,9 @@ pub struct CameraFile {
pub hot_pixels: Option<[f64; 2]>,
/// From camera C1: the seed of the fixed pattern.
pub pattern_seed: Option<u64>,
/// From camera C1: where charge beyond the full well goes: `"none"`,
/// `{ column = efficiency }` or `{ neighbors = efficiency }`.
pub blooming: Option<BloomingFile>,
/// The Gaussian blur's sigma in pixels, from camera C1: one for every channel, one
/// per channel, or 0 for none.
pub psf_sigma: Option<Sigma>,
@@ -89,6 +92,15 @@ pub struct CameraFile {
pub distortion: Option<[f64; 5]>,
}
/// Blooming in a scene file.
#[derive(Clone, Copy, Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum BloomingFile {
None,
Column(f64),
Neighbors(f64),
}
/// One sigma, or one per channel.
#[derive(Debug, Deserialize)]
#[serde(untagged)]
@@ -191,6 +203,13 @@ impl SceneFile {
if let Some(seed) = c.pattern_seed {
camera.detector.pattern_seed = seed;
}
if let Some(b) = c.blooming {
camera.detector.blooming = match b {
BloomingFile::None => Blooming::None,
BloomingFile::Column(efficiency) => Blooming::Column { efficiency },
BloomingFile::Neighbors(efficiency) => Blooming::Neighbors { efficiency },
};
}
if let Some([u, v]) = c.principal_point {
camera.principal_point = Some(Vector2::new(u, v));
}
@@ -471,7 +490,7 @@ mod tests {
let file: SceneFile = toml::from_str(&format!(
"{MINIMAL}\n[camera]\nwidth = 640\nexposure = 2e-3\nadc_bits = 10\nread_noise = 2.5\n\
dark_current = 0\nshot_noise = false\nprnu = 0.02\nhot_pixels = [1e-3, 20]\n\
pattern_seed = 9\n"
pattern_seed = 9\nblooming = {{ column = 0.25 }}\n"
))
.unwrap();
let camera = file.camera();
@@ -485,6 +504,7 @@ mod tests {
);
assert_eq!((d.prnu, d.dsnu, d.pattern_seed), (0.02, 0.1, 9));
assert_eq!((d.hot_pixel_fraction, d.hot_pixel_multiple), (1e-3, 20.0));
assert_eq!(d.blooming, Blooming::Column { efficiency: 0.25 });
for (line, psf) in [
(