commit 82a7b2e8552adde24bbb90d82845a20383fb32ab
parent c565ae49a99be1f1466f3708ea50e7355192123d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 9 Dec 2022 16:14:43 +0100
planeto: add support of discrete distribution of wavelengths
In shortwave, if spectrally variable radiance is defined on the source,
wavelengths are sampled from this data.
Diffstat:
3 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/src/planeto/htrdr_planeto.c b/src/planeto/htrdr_planeto.c
@@ -19,6 +19,7 @@
#include "core/htrdr.h"
#include "core/htrdr_ran_wlen_cie_xyz.h"
+#include "core/htrdr_ran_wlen_discrete.h"
#include "core/htrdr_ran_wlen_planck.h"
#include "core/htrdr_log.h"
@@ -232,6 +233,49 @@ error:
goto exit;
}
+static res_T
+setup_spectral_domain_sw
+ (struct htrdr_planeto* cmd,
+ const struct htrdr_planeto_args* args)
+{
+ res_T res = RES_OK;
+ ASSERT(cmd && args);
+ ASSERT(cmd->spectral_domain.type == HTRDR_SPECTRAL_SW);
+
+ /* Discrete distribution */
+ if(args->source.rnrl_filename) {
+ struct htrdr_planeto_source_spectrum spectrum;
+ struct htrdr_ran_wlen_discrete_create_args discrete_args;
+
+ res = htrdr_planeto_source_get_spectrum
+ (cmd->source, cmd->spectral_domain.wlen_range, &spectrum);
+ if(res != RES_OK) goto error;
+
+ discrete_args.get = htrdr_planeto_source_spectrum_at;
+ discrete_args.nwavelengths = spectrum.size;
+ discrete_args.context = &spectrum;
+ res = htrdr_ran_wlen_discrete_create
+ (cmd->htrdr, &discrete_args, &cmd->discrete);
+ if(res != RES_OK) goto error;
+
+ /* Planck distribution */
+ } else {
+ const size_t nintervals = compute_nintervals_for_spectral_cdf(cmd);
+
+ /* Use the source temperature as the reference temperature of the Planck
+ * distribution */
+ res = htrdr_ran_wlen_planck_create(cmd->htrdr,
+ cmd->spectral_domain.wlen_range, nintervals, args->source.temperature,
+ &cmd->planck);
+ if(res != RES_OK) goto error;
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
static INLINE res_T
setup_spectral_domain
(struct htrdr_planeto* cmd,
@@ -245,7 +289,6 @@ setup_spectral_domain
cmd->spectral_domain = args->spectral_domain;
/* Configure the spectral distribution */
- nintervals = compute_nintervals_for_spectral_cdf(cmd);
switch(cmd->spectral_domain.type) {
case HTRDR_SPECTRAL_LW:
@@ -255,6 +298,7 @@ setup_spectral_domain
/* Use as the reference temperature of the Planck distribution the
* maximum scene temperature which, in fact, should be the maximum ground
* temperature */
+ nintervals = compute_nintervals_for_spectral_cdf(cmd);
res = htrdr_ran_wlen_planck_create(cmd->htrdr,
cmd->spectral_domain.wlen_range, nintervals, ground_T_range[1],
&cmd->planck);
@@ -262,16 +306,13 @@ setup_spectral_domain
break;
case HTRDR_SPECTRAL_SW:
- /* Use the source temperature as the reference temperature of the Planck
- * distribution */
- res = htrdr_ran_wlen_planck_create(cmd->htrdr,
- cmd->spectral_domain.wlen_range, nintervals, args->source.temperature,
- &cmd->planck);
+ res = setup_spectral_domain_sw(cmd, args);
if(res != RES_OK) goto error;
break;
case HTRDR_SPECTRAL_SW_CIE_XYZ:
/* CIE XYZ distribution */
+ nintervals = compute_nintervals_for_spectral_cdf(cmd);
res = htrdr_ran_wlen_cie_xyz_create(cmd->htrdr,
cmd->spectral_domain.wlen_range, nintervals, &cmd->cie);
if(res != RES_OK) goto error;
diff --git a/src/planeto/htrdr_planeto_c.h b/src/planeto/htrdr_planeto_c.h
@@ -85,6 +85,7 @@ struct htrdr_planeto {
struct htrdr_planeto_spectral_args spectral_domain;
struct htrdr_ran_wlen_cie_xyz* cie; /* HTRDR_SPECTRAL_SW_CIE_XYZ */
struct htrdr_ran_wlen_planck* planck; /* HTRDR_SPECTRAL_<LW|SW> */
+ struct htrdr_ran_wlen_discrete* discrete; /* HTRDR_SPECTRAL_SW */
FILE* octrees_storage;
diff --git a/src/planeto/htrdr_planeto_draw_map.c b/src/planeto/htrdr_planeto_draw_map.c
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "planeto/htrdr_planeto_c.h"
+#include "planeto/htrdr_planeto_source.h"
#include "core/htrdr.h"
#include "core/htrdr_accum.h"
@@ -23,6 +24,7 @@
#include "core/htrdr_draw_map.h"
#include "core/htrdr_log.h"
#include "core/htrdr_ran_wlen_cie_xyz.h"
+#include "core/htrdr_ran_wlen_discrete.h"
#include "core/htrdr_ran_wlen_planck.h"
#include <rad-net/rnatm.h>
@@ -92,7 +94,21 @@ draw_pixel_xwave
r2 = ssp_rng_canonical(args->rng);
/* Sample a wavelength */
- wlen[0] = wlen[1] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf);
+ switch(cmd->spectral_domain.type) {
+ case HTRDR_SPECTRAL_LW:
+ wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf);
+ break;
+ case HTRDR_SPECTRAL_SW:
+ if(htrdr_planeto_source_does_radiance_vary_spectrally(cmd->source)) {
+ wlen[0] = htrdr_ran_wlen_discrete_sample(cmd->discrete, r0, r1, &pdf);
+ } else {
+ wlen[0] = htrdr_ran_wlen_planck_sample(cmd->planck, r0, r1, &pdf);
+ }
+ break;
+ default: FATAL("Unreachable code\n"); break;
+
+ }
+ wlen[1] = wlen[0];
pdf *= 1.e9; /* Transform the pdf from nm⁻¹ to m⁻¹ */
/* Find the band the wavelength belongs to and sample a quadrature point */