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:
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 */