commit 2ed9e2d029ab57811f294812b9abb2b6c271fd26
parent a6afdad1576ceb0ce47553399fbf259b25b6566a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 13 Oct 2020 11:38:58 +0200
Take into account very thin materials (e.g. leaves)
Diffstat:
3 files changed, 43 insertions(+), 23 deletions(-)
diff --git a/src/htrdr_ground.c b/src/htrdr_ground.c
@@ -162,6 +162,7 @@ parse_shape_interface
{
struct str str;
char* mtl_name_front = NULL;
+ char* mtl_name_thin = NULL;
char* mtl_name_back = NULL;
char* tk_ctx = NULL;
res_T res = RES_OK;
@@ -181,7 +182,11 @@ parse_shape_interface
/* Parse the name of the front/back faces */
mtl_name_front = strtok_r(str_get(&str), ":", &tk_ctx);
ASSERT(mtl_name_front); /* This can't be NULL */
+
+ /* Parse the back/thin material names */
+ mtl_name_thin = strtok_r(NULL, ":", &tk_ctx);
mtl_name_back = strtok_r(NULL, ":", &tk_ctx);
+ if(!mtl_name_back) mtl_name_back = mtl_name_thin;
if(!mtl_name_back) {
htrdr_log_err(htrdr,
"The material name of the shape back faces are missing `%s'.\n", name);
@@ -189,17 +194,28 @@ parse_shape_interface
goto error;
}
+ /* Fetch the interface material */
+ if(mtl_name_thin) {
+ interf->mtl_thin = htrdr_mtl_get(htrdr->mtl, mtl_name_thin);
+ if(!interf->mtl_thin) {
+ htrdr_log_err(htrdr,
+ "Invalid interface `%s:%s:%s'. "
+ "The material of the interface is unknown.\n",
+ mtl_name_front, mtl_name_thin, mtl_name_back);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
+
/* Fetch the front/back materials */
interf->mtl_front = htrdr_mtl_get(htrdr->mtl, mtl_name_front);
interf->mtl_back = htrdr_mtl_get(htrdr->mtl, mtl_name_back);
- if(!interf->mtl_front && !interf->mtl_back) {
- htrdr_log_err(htrdr,
- "Invalid interface `%s:%s'. "
- "The front and the back materials are both uknown.\n",
- mtl_name_front, mtl_name_back);
+ if(!interf->mtl_front && !interf->mtl_back && !interf->mtl_thin) {
+ htrdr_log_err(htrdr, "Invalid interface `%s'.\n", name);
res = RES_BAD_ARG;
goto error;
}
+
exit:
str_release(&str);
return res;
diff --git a/src/htrdr_interface.c b/src/htrdr_interface.c
@@ -123,33 +123,36 @@ htrdr_interface_create_bsdf
res_T res = RES_OK;
(void)pos;
ASSERT(htrdr && pos && hit && out_bsdf);
- ASSERT(interf && (interf->mtl_front || interf->mtl_back));
+ ASSERT(interf && (interf->mtl_front || interf->mtl_back || interf->mtl_thin));
ASSERT(htrdr && interf && pos && dir && hit && out_bsdf);
ASSERT(d3_is_normalized(dir));
- d3_normalize(N, d3_set_f3(N, hit->normal));
+ if(interf->mtl_thin) {
+ mat = interf->mtl_thin;
+ } else {
+ d3_normalize(N, d3_set_f3(N, hit->normal));
+ hit_side = d3_dot(N, dir) < 0 ? FRONT : BACK;
- hit_side = d3_dot(N, dir) < 0 ? FRONT : BACK;
-
- /* Retrieve the brdf of the material on the other side of the hit side */
- switch(hit_side) {
- case BACK: mat = interf->mtl_front; break;
- case FRONT: mat = interf->mtl_back; break;
- default: FATAL("Unreachable code.\n"); break;
- }
-
- /* Due to numerical issue the hit side might be wrong and thus the fetched
- * material might be undefined (e.g. semi-transparent materials). Handle this
- * issue by fetching the other material. */
- if(!mat) {
+ /* Retrieve the brdf of the material on the other side of the hit side */
switch(hit_side) {
- case BACK: mat = interf->mtl_back; break;
- case FRONT: mat = interf->mtl_front; break;
+ case BACK: mat = interf->mtl_front; break;
+ case FRONT: mat = interf->mtl_back; break;
default: FATAL("Unreachable code.\n"); break;
}
+
+ /* Due to numerical issue the hit side might be wrong and thus the fetched
+ * material might be undefined (e.g. semi-transparent materials). Handle this
+ * issue by fetching the other material. */
+ if(!mat) {
+ switch(hit_side) {
+ case BACK: mat = interf->mtl_back; break;
+ case FRONT: mat = interf->mtl_front; break;
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ }
+ ASSERT(mat);
}
- ASSERT(mat);
r = ssp_rng_canonical(rng);
diff --git a/src/htrdr_interface.h b/src/htrdr_interface.h
@@ -28,6 +28,7 @@ struct ssp_rng;
struct htrdr_interface {
const struct mrumtl* mtl_front;
const struct mrumtl* mtl_back;
+ const struct mrumtl* mtl_thin; /* != NULL <=> thin material */
};
static const struct htrdr_interface HTRDR_INTERFACE_NULL;