solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

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:
Msrc/ssol_draw_pt.c | 23++++++++---------------
Msrc/ssol_material.c | 95++++++++++++++++++++++++++++---------------------------------------------------
Msrc/ssol_material_c.h | 4++--
Msrc/ssol_solver.c | 34+++++++++++++---------------------
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; }