diff --git a/README.md b/README.md index 6d44154..159c339 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,10 @@ This writes `minkowski_accel_000000.png` through input; the acceleration generator is only a reproducible flat-spacetime test fixture. The current movie path still renders frames independently while the time-slab/RayPool scheduler is implemented next, so it must not yet be used -as a performance measurement for numerical-relativity data. Movie mode uses -the same `1e-5` exposure by default when `--exposure` is omitted; this differs -from the legacy single-frame default so the accelerated test catalog does not -clip to white. +as a performance measurement for numerical-relativity data. The current +synthetic test catalog uses global default exposure `1e-3`; the accelerated +benchmark explicitly uses `1e-5` because its physical Doppler blue shift +otherwise clips the later frames. PNG output is optional so the default build has no `libpng` dependency. Build with `make ENABLE_PNG=1`, then select it with a `.png` output path: @@ -136,9 +136,10 @@ production refinement threshold. `--look-ra-deg` and `--look-dec-deg` rotate that fixed tetrad so its forward axis is the corresponding catalog direction; their defaults reproduce the original `-Z` view. `--exposure` converts a catalog's physical flux -normalization to the prototype HDR scale. Its default preserves the synthetic -catalog benchmark; a 2MASS blackbody normalization in steradians requires a -much larger display exposure such as the example above. The optics path +normalization to the prototype HDR scale. The current synthetic catalog is +calibrated for default exposure `1e-3`; a 2MASS blackbody normalization in +steradians requires a much larger display exposure such as the example above. +The optics path integrates each fitted Planck spectrum through CIE 1931 color-matching functions and converts the resulting radiance to linear sRGB; it does not use an empirical color-temperature RGB approximation. diff --git a/src/main.c b/src/main.c index a089ff1..e14e1b6 100644 --- a/src/main.c +++ b/src/main.c @@ -17,7 +17,6 @@ typedef struct { int width, height; int coarse_cell_pixels; int draw_mesh; - int exposure_was_set; double horizontal_fov_deg, look_ra_deg, look_dec_deg, exposure; double observer_inward_speed; PointSpreadFunction psf; @@ -98,7 +97,7 @@ static int parse_args(int argc, char **argv, Settings *s, .horizontal_fov_deg = 30.0, .look_ra_deg = 270.0, .look_dec_deg = 0.0, - .exposure = 100.0, + .exposure = 1e-3, .psf = {2.7, 4.5}, .catalog_path = "assets/sky_grid_5deg.csv", .output_path = "output/imgs/minkowski_sky.ppm", @@ -128,7 +127,6 @@ static int parse_args(int argc, char **argv, Settings *s, !parse_dec_deg(argv[++i], &s->look_dec_deg)) { } else if (!strcmp(argv[i], "--exposure") && i + 1 < argc && !parse_positive(argv[++i], &s->exposure)) { - s->exposure_was_set = 1; } else if (!strcmp(argv[i], "--observer-inward-speed") && i + 1 < argc && !parse_speed(argv[++i], &s->observer_inward_speed)) { } else if (!strcmp(argv[i], "--psf-fwhm-pixels") && i + 1 < argc && @@ -235,14 +233,7 @@ static int render_movie(const Settings *s, const StarCatalog *catalog, const SpacetimeSource *spacetime) { ObserverTrack track = {0}; Movie movie = {0}; - Settings frame_settings = *s; int result = -1; - /* The single-image sky fixture historically used an exposure intended for - * static inspection. A near-light-speed movie makes it clip immediately; - * retain that single-frame default but choose a legible, fixed test exposure - * for sequences unless the caller explicitly supplied --exposure. */ - if (!frame_settings.exposure_was_set) - frame_settings.exposure = 1e-5; if (s->observer_track_path == NULL || observer_track_load_csv(&track, s->observer_track_path) || movie_init(&movie, &track, s->movie_start_time, s->movie_duration, @@ -251,8 +242,8 @@ static int render_movie(const Settings *s, const StarCatalog *catalog, for (size_t i = 0; i < movie.frame_count; ++i) { char output_path[PATH_MAX]; if (frame_output_path(output_path, s, movie.frames[i].frame_id) || - render_observer_frame(&frame_settings, catalog, spacetime, - &movie.frames[i].observer, output_path)) + render_observer_frame(s, catalog, spacetime, &movie.frames[i].observer, + output_path)) goto done; } result = 0; diff --git a/tests/test_frame.c b/tests/test_frame.c index 1c93223..1ed453c 100644 --- a/tests/test_frame.c +++ b/tests/test_frame.c @@ -9,6 +9,7 @@ int main(void) { const int width = 100, height = 100; + const double test_exposure = 1e-3; const PointSpreadFunction psf = {.fwhm_pixels = 2.7, .moffat_beta = 4.5}; const GeodesicTraceConfig trace = {.coordinate_time_step = 0.25, .max_steps = 100}; @@ -25,7 +26,8 @@ int main(void) { frame_lens_mesh_trace(&mesh, &spacetime, &observer, &trace)) goto done; const size_t images = - frame_splat_catalog(&mesh, &catalog, hdr, width, height, 100.0, &psf); + frame_splat_catalog(&mesh, &catalog, hdr, width, height, test_exposure, + &psf); if (images != 1 || hdr[3 * (50 * width + 50)] <= 0.0) { fputs("flat-space inverse lens-map regression failed\n", stderr); goto done; @@ -42,10 +44,10 @@ int main(void) { omp_set_dynamic(0); omp_set_num_threads(1); const size_t serial_images = frame_splat_catalog( - &mesh, &catalog, serial_hdr, width, height, 100.0, &psf); + &mesh, &catalog, serial_hdr, width, height, test_exposure, &psf); omp_set_num_threads(4); const size_t parallel_images = frame_splat_catalog( - &mesh, &catalog, parallel_hdr, width, height, 100.0, &psf); + &mesh, &catalog, parallel_hdr, width, height, test_exposure, &psf); omp_set_num_threads(original_threads); for (int value = 0; value < width * height * 3; ++value) if (fabs(serial_hdr[value] - parallel_hdr[value]) > @@ -100,7 +102,7 @@ int main(void) { if (frame_lens_mesh_build_coarse(&fine_mesh, width, height, 1, 0.1) || frame_lens_mesh_trace(&fine_mesh, &spacetime, &observer, &trace) || frame_splat_catalog(&fine_mesh, &fine_catalog, hdr, width, height, - 100.0, &psf) != 1) { + test_exposure, &psf) != 1) { fputs("fine source-triangle containment regression failed\n", stderr); frame_lens_mesh_destroy(&fine_mesh); goto done;