htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit af4a211c7373cfa2409447011f664bb91f2d8079
parent 0fcbe4efcec7a158ebb72fab458827e2c363928b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 12 Sep 2018 14:04:01 +0200

Output colored image in CIE 1931 XYZ color space

Diffstat:
Mcmake/CMakeLists.txt | 3+--
Msrc/htrdr.c | 25+++++++++++++++----------
Msrc/htrdr_buffer.c | 2+-
Msrc/htrdr_draw_radiance_sw.c | 92++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/htrdr_solve.h | 2+-
5 files changed, 72 insertions(+), 52 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -93,11 +93,10 @@ target_link_libraries(htrdr HTCP HTGOP HTMIE RSys Star3D Star3DAW StarSF StarSP if(CMAKE_COMPILER_IS_GNUCC) target_link_libraries(htrdr m) - set_target_properties(htrdr PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) + set_target_properties(htrdr PROPERTIES LINK_FLAGS "${OpenMP_C_FLAGS}") endif() set_target_properties(htrdr PROPERTIES - DEFINE_SYMBOL HTRDR_SHARED_BUILD COMPILE_FLAGS "${OpenMP_C_FLAGS}" VERSION ${VERSION} SOVERSION ${VERSION_MAJOR}) diff --git a/src/htrdr.c b/src/htrdr.c @@ -110,8 +110,8 @@ dump_accum_buffer (void)stream_name; htrdr_buffer_get_layout(buf, &layout); - if(layout.elmt_size != sizeof(struct htrdr_accum) - || layout.alignment < ALIGNOF(struct htrdr_accum)) { + if(layout.elmt_size != sizeof(struct htrdr_accum[3])/*#channels*/ + || layout.alignment < ALIGNOF(struct htrdr_accum[3])) { htrdr_log_err(htrdr, "%s: invalid buffer layout. " "The pixel size must be the size of an accumulator.\n", @@ -120,12 +120,17 @@ dump_accum_buffer goto error; } + fprintf(stream, "%lu %lu\n", layout.width, layout.height); FOR_EACH(y, 0, layout.height) { FOR_EACH(x, 0, layout.width) { - const struct htrdr_accum* accum = htrdr_buffer_at(buf, x, y); - const double E = accum->nweights - ? accum->sum_weights / (double)accum->nweights : 0; - fprintf(stream, "%g ", E); + const struct htrdr_accum* accums = htrdr_buffer_at(buf, x, y); + int i; + FOR_EACH(i, 0, 3) { + const double E = accums[i].nweights + ? accums[i].sum_weights / (double)accums[i].nweights : 0; + fprintf(stream, "%g ", E); + } + fprintf(stream, "\n"); } fprintf(stream, "\n"); } @@ -258,9 +263,9 @@ htrdr_init res = htrdr_buffer_create(htrdr, args->image.definition[0], /* Width */ args->image.definition[1], /* Height */ - args->image.definition[0]*sizeof(struct htrdr_accum), /* Pitch */ - sizeof(struct htrdr_accum), /* Element size */ - 16, /* Alignment */ + args->image.definition[0]*sizeof(struct htrdr_accum[3]), /* Pitch */ + sizeof(struct htrdr_accum[3]), + ALIGNOF(struct htrdr_accum[3]), /* Alignment */ &htrdr->buf); if(res != RES_OK) goto error; @@ -346,7 +351,7 @@ htrdr_run(struct htrdr* htrdr) if(res != RES_OK) goto error; time_sub(&t0, time_current(&t1), &t0); time_dump(&t0, TIME_ALL, NULL, buf, sizeof(buf)); - htrdr_log(htrdr, "Elapsed time: %s\n", buf); + htrdr_log(htrdr, "Rendering time: %s\n", buf); res = dump_accum_buffer (htrdr, htrdr->buf, str_cget(&htrdr->output_name), htrdr->output); diff --git a/src/htrdr_buffer.c b/src/htrdr_buffer.c @@ -69,7 +69,7 @@ htrdr_buffer_create res = RES_BAD_ARG; goto error; } - if(pitch < width) { + if(pitch < width*elmtsz) { htrdr_log_err(htrdr, "invalid buffer pitch `%lu' wrt the buffer width `%lu'. " "The buffer pitch cannot be less than the buffer width.\n", diff --git a/src/htrdr_draw_radiance_sw.c b/src/htrdr_draw_radiance_sw.c @@ -64,10 +64,10 @@ draw_tile npixels *= npixels; FOR_EACH(mcode, 0, npixels) { - struct htrdr_accum* pix_accum; + struct htrdr_accum* pix_accums; size_t ipix_tile[2]; /* Pixel coord in the tile */ size_t ipix[2]; /* Pixel coord in the buffer */ - size_t i; + size_t ichannel; ipix_tile[0] = morton2D_decode((uint32_t)(mcode>>0)); if(ipix_tile[0] >= tile_sz[0]) continue; /* Pixel is out of tile */ @@ -79,41 +79,57 @@ draw_tile ipix[1] = tile_org[1] + ipix_tile[1]; /* Fetch and reset the pixel accumulator */ - pix_accum = htrdr_buffer_at(buf, ipix[0], ipix[1]); - *pix_accum = HTRDR_ACCUM_NULL; - - FOR_EACH(i, 0, spp) { - double pix_samp[2]; - double ray_org[3]; - double ray_dir[3]; - double weight; - size_t iband; - size_t iquad; - - /* Sample a position into the pixel, in the normalized image plane */ - pix_samp[0] = ((double)ipix[0] + ssp_rng_canonical(rng)) * pix_sz[0]; - pix_samp[1] = ((double)ipix[1] + ssp_rng_canonical(rng)) * pix_sz[1]; - - /* Generate a ray starting from the pinhole camera and passing through the - * pixel sample */ - htrdr_camera_ray(cam, pix_samp, ray_org, ray_dir); - - /* Sample a spectral band and a quadrature point */ - htrdr_sky_sample_sw_spectral_data_CIE_1931_X - (htrdr->sky, rng, &iband, &iquad); - - /* Compute the radiance that reach the pixel through the ray */ - weight = htrdr_compute_radiance_sw - (htrdr, ithread, rng, ray_org, ray_dir, iband, iquad); - ASSERT(weight >= 0); - - /* Update the pixel accumulator */ - pix_accum->sum_weights += weight; - pix_accum->sum_weights_sqr += weight*weight; - pix_accum->nweights += 1; + pix_accums = htrdr_buffer_at(buf, ipix[0], ipix[1]); + + FOR_EACH(ichannel, 0, 3) { + size_t isamp; + pix_accums[ichannel] = HTRDR_ACCUM_NULL; + + FOR_EACH(isamp, 0, spp) { + double pix_samp[2]; + double ray_org[3]; + double ray_dir[3]; + double weight; + size_t iband; + size_t iquad; + + /* Sample a position into the pixel, in the normalized image plane */ + pix_samp[0] = ((double)ipix[0] + ssp_rng_canonical(rng)) * pix_sz[0]; + pix_samp[1] = ((double)ipix[1] + ssp_rng_canonical(rng)) * pix_sz[1]; + + /* Generate a ray starting from the pinhole camera and passing through the + * pixel sample */ + htrdr_camera_ray(cam, pix_samp, ray_org, ray_dir); + + /* Sample a spectral band and a quadrature point */ + switch(ichannel) { + case 0: + htrdr_sky_sample_sw_spectral_data_CIE_1931_X + (htrdr->sky, rng, &iband, &iquad); + break; + case 1: + htrdr_sky_sample_sw_spectral_data_CIE_1931_Y + (htrdr->sky, rng, &iband, &iquad); + break; + case 2: + htrdr_sky_sample_sw_spectral_data_CIE_1931_Z + (htrdr->sky, rng, &iband, &iquad); + break; + default: FATAL("Unreachable code.\n"); break; + } + + /* Compute the radiance that reach the pixel through the ray */ + weight = htrdr_compute_radiance_sw + (htrdr, ithread, rng, ray_org, ray_dir, iband, iquad); + ASSERT(weight >= 0); + + /* Update the pixel accumulator */ + pix_accums[ichannel].sum_weights += weight; + pix_accums[ichannel].sum_weights_sqr += weight*weight; + pix_accums[ichannel].nweights += 1; + } } } - return RES_OK; } @@ -142,11 +158,11 @@ htrdr_draw_radiance_sw htrdr_buffer_get_layout(buf, &layout); ASSERT(layout.width || layout.height || layout.elmt_size); - if(layout.elmt_size != sizeof(struct htrdr_accum) - || layout.alignment < ALIGNOF(struct htrdr_accum)) { + if(layout.elmt_size != sizeof(struct htrdr_accum[3])/*#channels*/ + || layout.alignment < ALIGNOF(struct htrdr_accum[3])) { htrdr_log_err(htrdr, "%s: invalid buffer layout. " - "The pixel size must be the size of an accumulator.\n", + "The pixel size must be the size of 3 * accumulators.\n", FUNC_NAME); res = RES_BAD_ARG; goto error; diff --git a/src/htrdr_solve.h b/src/htrdr_solve.h @@ -48,6 +48,6 @@ htrdr_draw_radiance_sw (struct htrdr* htrdr, const struct htrdr_camera* cam, const size_t spp, /* #samples per pixel, i.e. #realisations */ - struct htrdr_buffer* buf); /* Buffer of struct htrdr_accum */ + struct htrdr_buffer* buf); /* Buffer of struct htrdr_accum[3] */ #endif /* HTRDR_SOLVE_H */