commit ec19567c234437e145aa5c18fe54cc35b6aca76c
parent daf7e6f57a69994ff5deab3965d4d848e096d6f0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 4 Sep 2017 15:37:26 +0200
Use the SSF library update that removes the BxDF abstraction
Diffstat:
4 files changed, 56 insertions(+), 100 deletions(-)
diff --git a/src/ssol_draw_pt.c b/src/ssol_draw_pt.c
@@ -38,7 +38,6 @@
******************************************************************************/
struct thread_context {
struct ssp_rng* rng;
- struct ssf_bsdf* bsdf;
struct ranst_sun_wl* ran_wl;
float up[3];
};
@@ -48,7 +47,6 @@ thread_context_release(struct thread_context* ctx)
{
ASSERT(ctx);
if(ctx->rng) SSP(rng_ref_put(ctx->rng));
- if(ctx->bsdf) SSF(bsdf_ref_put(ctx->bsdf));
if(ctx->ran_wl) ranst_sun_wl_ref_put(ctx->ran_wl);
}
@@ -57,16 +55,10 @@ thread_context_init
(struct mem_allocator* allocator,
struct thread_context* ctx)
{
- res_T res = RES_OK;
ASSERT(ctx);
+ (void)allocator;
memset(ctx, 0, sizeof(ctx[0]));
- res = ssf_bsdf_create(allocator, &ctx->bsdf);
- if(res != RES_OK) goto error;
-exit:
- return res;
-error:
- thread_context_release(ctx);
- goto exit;
+ return RES_OK;
}
static void
@@ -143,6 +135,7 @@ Li(struct ssol_scene* scn,
struct ray_data ray_data = RAY_DATA_NULL;
struct ssol_instance* inst;
struct ssol_material* mtl;
+ struct ssf_bsdf* bsdf = NULL;
const struct shaded_shape* sshape;
struct ssol_surface_fragment frag;
size_t isshape;
@@ -229,9 +222,8 @@ Li(struct ssol_scene* scn,
/* Shaded normal may look backward the outgoing direction */
if(d3_dot(N, wo) > 0) break;
- SSF(bsdf_clear(ctx->bsdf));
- res = material_setup_bsdf
- (mtl, &frag, wl, &medium, 1/*Rendering*/, ctx->bsdf);
+ if(bsdf) SSF(bsdf_ref_put(bsdf)), bsdf = NULL;
+ res = material_create_bsdf(mtl, &frag, wl, &medium, 1/*Rendering*/, &bsdf);
if(res != RES_OK) goto error;
/* Update the ray */
@@ -248,11 +240,11 @@ Li(struct ssol_scene* scn,
d3_minus(wo, wo);
if(scn->sun) {
L += throughput * sun_lighting
- (scn->sun, view, &ray_data, ctx->bsdf, wo, N, ray_org);
+ (scn->sun, view, &ray_data, bsdf, wo, N, ray_org);
}
/* Sampling a bounce direction */
- R = ssf_bsdf_sample(ctx->bsdf, ctx->rng, wo, N, wi, &type, &pdf);
+ R = ssf_bsdf_sample(bsdf, ctx->rng, wo, N, wi, &type, &pdf);
ASSERT(0 <= R && R <= 1);
/* Due to the shading normal, the sampled direction may point in the wrong
@@ -282,6 +274,7 @@ Li(struct ssol_scene* scn,
d3_splat(val, L);
exit:
+ if(bsdf) SSF(bsdf_ref_put(bsdf));
ssol_medium_clear(&medium);
return res;
error:
diff --git a/src/ssol_material.c b/src/ssol_material.c
@@ -88,16 +88,13 @@ shade_normal_default
}
static res_T
-setup_dielectric_bsdf
+create_dielectric_bsdf
(const struct ssol_material* mtl,
const struct ssol_surface_fragment* fragment,
const double wavelength, /* In nanometer */
const struct ssol_medium* medium,
- struct ssf_bsdf* bsdf)
+ struct ssf_bsdf** bsdf)
{
- struct ssf_bxdf* brdf = NULL;
- struct ssf_bxdf* btdf = NULL;
- struct ssf_fresnel* fresnel = NULL;
double eta_i, eta_t;
res_T res = RES_OK;
ASSERT(mtl && fragment && mtl->type == SSOL_MATERIAL_DIELECTRIC);
@@ -114,37 +111,25 @@ setup_dielectric_bsdf
eta_t = ssol_data_get_value(&mtl->in_medium.refractive_index, wavelength);
#define CALL(Func) { res = Func; if(res != RES_OK) goto error; } (void)0
- /* Setup the reflective part */
- CALL(ssf_fresnel_create
- (mtl->dev->allocator, &ssf_fresnel_dielectric_dielectric, &fresnel));
- CALL(ssf_fresnel_dielectric_dielectric_setup(fresnel, eta_i, eta_t));
- CALL(ssf_bxdf_create(mtl->dev->allocator, &ssf_specular_reflection, &brdf));
- CALL(ssf_specular_reflection_setup(brdf, fresnel));
- /* Setup the transmissive part */
- CALL(ssf_bxdf_create(mtl->dev->allocator, &ssf_specular_transmission, &btdf));
- CALL(ssf_specular_transmission_setup(btdf, eta_i, eta_t));
- /* Setup the scattering function */
- CALL(ssf_bsdf_add(bsdf, brdf, 0.5));
- CALL(ssf_bsdf_add(bsdf, btdf, 0.5));
+ CALL(ssf_bsdf_create
+ (mtl->dev->allocator, &ssf_specular_dielectric_dielectric_interface, bsdf));
+ CALL(ssf_specular_dielectric_dielectric_interface_setup(*bsdf, eta_i, eta_t));
#undef CALL
exit:
- if(brdf) SSF(bxdf_ref_put(brdf));
- if(btdf) SSF(bxdf_ref_put(btdf));
- if(fresnel) SSF(fresnel_ref_put(fresnel));
return res;
error:
+ if(bsdf) SSF(bsdf_ref_put(*bsdf)), bsdf = NULL;
goto exit;
}
static res_T
-setup_matte_bsdf
+create_matte_bsdf
(const struct ssol_material* mtl,
const struct ssol_surface_fragment* fragment,
const double wavelength, /* In nanometer */
- struct ssf_bsdf* bsdf)
+ struct ssf_bsdf** bsdf)
{
- struct ssf_bxdf* brdf = NULL;
double reflectivity;
res_T res;
ASSERT(mtl && fragment && mtl->type == SSOL_MATERIAL_MATTE);
@@ -155,31 +140,26 @@ setup_matte_bsdf
(mtl->dev, mtl->buf, wavelength, fragment, &reflectivity);
/* Setup the BRDF */
- res = ssf_bxdf_create(mtl->dev->allocator, &ssf_lambertian_reflection, &brdf);
+ res = ssf_bsdf_create(mtl->dev->allocator, &ssf_lambertian_reflection, bsdf);
if(res != RES_OK) goto error;
- res = ssf_lambertian_reflection_setup(brdf, reflectivity);
- if(res != RES_OK) goto error;
-
- /* Setup the BSDF */
- res = ssf_bsdf_add(bsdf, brdf, 1.0);
+ res = ssf_lambertian_reflection_setup(*bsdf, reflectivity);
if(res != RES_OK) goto error;
exit:
- if(brdf) SSF(bxdf_ref_put(brdf));
return res;
error:
+ if(bsdf) SSF(bsdf_ref_put(*bsdf)), bsdf = NULL;
goto exit;
}
static res_T
-setup_mirror_bsdf
+create_mirror_bsdf
(const struct ssol_material* mtl,
const struct ssol_surface_fragment* fragment,
const double wavelength, /* In nanometer */
const int rendering,
- struct ssf_bsdf* bsdf)
+ struct ssf_bsdf** bsdf)
{
- struct ssf_bxdf* brdf = NULL;
struct ssf_fresnel* fresnel = NULL;
struct ssf_microfacet_distribution* distrib = NULL;
double roughness;
@@ -202,9 +182,9 @@ setup_mirror_bsdf
/* Setup the BRDF */
if(roughness == 0) { /* Purely specular reflection */
- res = ssf_bxdf_create(mtl->dev->allocator, &ssf_specular_reflection, &brdf);
+ res = ssf_bsdf_create(mtl->dev->allocator, &ssf_specular_reflection, bsdf);
if(res != RES_OK) goto error;
- res = ssf_specular_reflection_setup(brdf, fresnel);
+ res = ssf_specular_reflection_setup(*bsdf, fresnel);
if(res != RES_OK) goto error;
} else { /* Glossy reflection */
res = ssf_microfacet_distribution_create
@@ -217,38 +197,33 @@ setup_mirror_bsdf
* evaluated and consequently it returns an invalid result for direct
* lighting. */
if(rendering) {
- res = ssf_bxdf_create
- (mtl->dev->allocator, &ssf_microfacet_reflection, &brdf);
+ res = ssf_bsdf_create
+ (mtl->dev->allocator, &ssf_microfacet_reflection, bsdf);
} else {
- res = ssf_bxdf_create
- (mtl->dev->allocator, &ssf_microfacet2_reflection, &brdf);
+ res = ssf_bsdf_create
+ (mtl->dev->allocator, &ssf_microfacet2_reflection, bsdf);
}
if(res != RES_OK) goto error;
- res = ssf_microfacet_reflection_setup(brdf, fresnel, distrib);
+ res = ssf_microfacet_reflection_setup(*bsdf, fresnel, distrib);
if(res != RES_OK) goto error;
}
- /* Setup the BSDF */
- res = ssf_bsdf_add(bsdf, brdf, 1.0);
- if(res != RES_OK) goto error;
-
exit:
- if(brdf) SSF(bxdf_ref_put(brdf));
if(fresnel) SSF(fresnel_ref_put(fresnel));
if(distrib) SSF(microfacet_distribution_ref_put(distrib));
return res;
error:
+ if(bsdf) SSF(bsdf_ref_put(*bsdf)), bsdf = NULL;
goto exit;
}
static res_T
-setup_thin_dielectric_bsdf
+create_thin_dielectric_bsdf
(const struct ssol_material* mtl,
const struct ssol_surface_fragment* fragment,
const double wavelength, /* In nanometer */
- struct ssf_bsdf* bsdf)
+ struct ssf_bsdf** bsdf)
{
- struct ssf_bxdf* bxdf = NULL;
double thickness;
double absorption;
double eta_i;
@@ -266,21 +241,17 @@ setup_thin_dielectric_bsdf
thickness = mtl->data.thin_dielectric.thickness;
/* Setup the BxDF */
- res = ssf_bxdf_create
- (mtl->dev->allocator, &ssf_thin_specular_dielectric, &bxdf);
+ res = ssf_bsdf_create
+ (mtl->dev->allocator, &ssf_thin_specular_dielectric, bsdf);
if(res != RES_OK) goto error;
res = ssf_thin_specular_dielectric_setup
- (bxdf, absorption, eta_i, eta_t, thickness);
- if(res != RES_OK) goto error;
-
- /* Setup the BSDF */
- res = ssf_bsdf_add(bsdf, bxdf, 1.0);
+ (*bsdf, absorption, eta_i, eta_t, thickness);
if(res != RES_OK) goto error;
exit:
- if(bxdf) SSF(bxdf_ref_put(bxdf));
return res;
error:
+ if(bsdf) SSF(bsdf_ref_put(*bsdf)), bsdf = NULL;
goto exit;
}
@@ -679,30 +650,30 @@ material_shade_normal
}
res_T
-material_setup_bsdf
+material_create_bsdf
(const struct ssol_material* mtl,
const struct ssol_surface_fragment* fragment,
const double wavelength, /* In nanometer */
const struct ssol_medium* medium,
const int rendering, /* Is BSDF used for rendering */
- struct ssf_bsdf* bsdf)
+ struct ssf_bsdf** bsdf)
{
res_T res = RES_OK;
ASSERT(mtl);
switch(mtl->type) {
case SSOL_MATERIAL_DIELECTRIC:
- res = setup_dielectric_bsdf
+ res = create_dielectric_bsdf
(mtl, fragment, wavelength, medium, bsdf);
break;
case SSOL_MATERIAL_MATTE:
- res = setup_matte_bsdf(mtl, fragment, wavelength, bsdf);
+ res = create_matte_bsdf(mtl, fragment, wavelength, bsdf);
break;
case SSOL_MATERIAL_MIRROR:
- res = setup_mirror_bsdf(mtl, fragment, wavelength, rendering, bsdf);
+ res = create_mirror_bsdf(mtl, fragment, wavelength, rendering, bsdf);
break;
case SSOL_MATERIAL_THIN_DIELECTRIC:
- res = setup_thin_dielectric_bsdf(mtl, fragment, wavelength, bsdf);
+ res = create_thin_dielectric_bsdf(mtl, fragment, wavelength, bsdf);
break;
case SSOL_MATERIAL_VIRTUAL: /* Nothing to shade */ break;
default: FATAL("Unreachable code\n"); break;
diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h
@@ -78,13 +78,13 @@ material_shade_normal
double N[3]);
extern LOCAL_SYM res_T
-material_setup_bsdf
+material_create_bsdf
(const struct ssol_material* mtl,
const struct ssol_surface_fragment* fragment,
const double wavelength, /* In nanometer */
const struct ssol_medium* medium, /* Current medium */
const int rendering, /* Is material used for rendering purposes */
- struct ssf_bsdf* bsdf); /* Bidirectional Scattering Distribution Function */
+ struct ssf_bsdf** bsdf); /* Bidirectional Scattering Distribution Function */
extern LOCAL_SYM res_T
material_get_next_medium
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -51,7 +51,6 @@
******************************************************************************/
struct thread_context {
struct ssp_rng* rng;
- struct ssf_bsdf* bsdf;
struct mc_data cos_factor;
struct mc_data absorbed;
struct mc_data shadowed;
@@ -69,7 +68,6 @@ thread_context_release(struct thread_context* ctx)
{
ASSERT(ctx);
if(ctx->rng) SSP(rng_ref_put(ctx->rng));
- if(ctx->bsdf) SSF(bsdf_ref_put(ctx->bsdf));
htable_receiver_release(&ctx->mc_rcvs);
htable_sampled_release(&ctx->mc_samps);
darray_path_release(&ctx->paths);
@@ -78,22 +76,12 @@ thread_context_release(struct thread_context* ctx)
static res_T
thread_context_init(struct mem_allocator* allocator, struct thread_context* ctx)
{
- res_T res = RES_OK;
ASSERT(ctx);
-
memset(ctx, 0, sizeof(ctx[0]));
htable_receiver_init(allocator, &ctx->mc_rcvs);
htable_sampled_init(allocator, &ctx->mc_samps);
darray_path_init(allocator, &ctx->paths);
-
- res = ssf_bsdf_create(allocator, &ctx->bsdf);
- if(res != RES_OK) goto error;
-
-exit:
- return res;
-error:
- thread_context_release(ctx);
- goto exit;
+ return RES_OK;
}
/* Define a copy functor only for consistency since this function will not be
@@ -105,7 +93,6 @@ thread_context_copy
res_T res = RES_OK;
ASSERT(dst && src);
dst->rng = src->rng;
- dst->bsdf = src->bsdf;
dst->cos_factor = src->cos_factor;
dst->absorbed = src->absorbed;
dst->shadowed = src->shadowed;
@@ -374,18 +361,18 @@ point_update_from_hit
static FINLINE res_T
point_shade
(struct point* pt,
- struct ssf_bsdf* bsdf,
struct ssol_medium* medium,
struct ssp_rng* rng,
double dir[3])
{
struct ssol_material* mtl;
struct ssol_surface_fragment frag;
+ struct ssf_bsdf* bsdf = NULL;
double r = 1;
double wi[3], N[3], pdf;
int type = 0;
res_T res;
- ASSERT(pt && bsdf && medium && rng && dir);
+ ASSERT(pt && medium && rng && dir);
/* TODO ensure that if `prim' was sampled, then the surface fragment setup
* remains valid in *all* situations, i.e. even though the point primitive
@@ -402,9 +389,9 @@ point_shade
/* Shade the surface fragment */
mtl = point_get_material(pt);
- SSF(bsdf_clear(bsdf));
- res = material_setup_bsdf(mtl, &frag, pt->wl, medium, 0, bsdf);
- if(res != RES_OK) return res;
+
+ res = material_create_bsdf(mtl, &frag, pt->wl, medium, 0, &bsdf);
+ if(res != RES_OK) goto error;
/* Perturbe the normal */
material_shade_normal(mtl, &frag, pt->wl, N);
@@ -435,7 +422,12 @@ point_shade
pt->weight = pt->incoming_weight - pt->absorbed_irradiance;
if(type & SSF_TRANSMISSION) material_get_next_medium(mtl, medium, medium);
- return RES_OK;
+
+exit:
+ if(bsdf) SSF(bsdf_ref_put(bsdf));
+ return res;
+error:
+ goto exit;
}
static FINLINE void
@@ -814,7 +806,7 @@ trace_radiative_path
} else {
/* Modulate the point weight wrt its scattering functions and generate
* an outgoing direction */
- res = point_shade(&pt, thread_ctx->bsdf, &medium, thread_ctx->rng, pt.dir);
+ res = point_shade(&pt, &medium, thread_ctx->rng, pt.dir);
if(res != RES_OK) goto error;
}