star-sf

Set of surface and volume scattering functions
git clone git://git.meso-star.fr/star-sf.git
Log | Files | Refs | README | LICENSE

commit 941277a1bc97837d22befd804c6de6368f099cb8
parent 8621fd538153443dd896cf59a3dffb07a8c94595
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 28 Sep 2016 19:09:12 +0200

Remove the reflectivity parameter from the microfacet BRDF

Diffstat:
Msrc/ssf.h | 1-
Msrc/ssf_microfacet_reflection.c | 12+++---------
Msrc/test_ssf_microfacet_reflection.c | 46+++++++++++++++++++---------------------------
3 files changed, 22 insertions(+), 37 deletions(-)

diff --git a/src/ssf.h b/src/ssf.h @@ -295,7 +295,6 @@ ssf_lambertian_reflection_setup res_T ssf_microfacet_reflection_setup (struct ssf_bxdf* data, - const double reflectivity, struct ssf_fresnel* fresnel, struct ssf_microfacet_distribution* distrib); diff --git a/src/ssf_microfacet_reflection.c b/src/ssf_microfacet_reflection.c @@ -20,7 +20,6 @@ #include <rsys/double3.h> struct microfacet_reflection { - double reflectivity; struct ssf_fresnel* fresnel; struct ssf_microfacet_distribution* distrib; }; @@ -34,7 +33,6 @@ microfacet_reflection_init(struct mem_allocator* allocator, void* data) struct microfacet_reflection* bxdf = data; ASSERT(bxdf); (void)allocator; - bxdf->reflectivity = 0.0; bxdf->fresnel = NULL; bxdf->distrib = NULL; return RES_OK; @@ -76,7 +74,7 @@ microfacet_reflection_eval G = MMIN((2*cos_wh_N*cos_wo_N)/cos_wh_wo, (2*cos_wh_N*cos_wi_N)/cos_wh_wo); G = MMIN(1, G); - return bxdf->reflectivity * F*D*G/(4*cos_wi_N*cos_wo_N); + return F*D*G/(4*cos_wi_N*cos_wo_N); } static FINLINE double @@ -103,8 +101,7 @@ microfacet_reflection_sample ssf_microfacet_distribution_sample(bxdf->distrib, u, v, wo, N, wh, &pdf_wh); reflect(dir, wo, wh); *pdf = pdf_wh / (4.0*fabs(d3_dot(wo, wh))); /* TODO check this */ - if(d3_dot(dir, N) <= 0.0) return 0.0; - R = microfacet_reflection_eval(bxdf, wo, N, dir); + R = d3_dot(dir, N) > 0 ? microfacet_reflection_eval(bxdf, wo, N, dir) : 0; d3_set(wi, dir); return R; } @@ -149,19 +146,16 @@ const struct ssf_bxdf_type ssf_microfacet_reflection = { res_T ssf_microfacet_reflection_setup (struct ssf_bxdf* bxdf, - const double reflectivity, struct ssf_fresnel* fresnel, struct ssf_microfacet_distribution* distrib) { struct microfacet_reflection* microfacet; - if(!bxdf || reflectivity < 0 || reflectivity > 1 || !fresnel || !distrib) + if(!bxdf || !fresnel || !distrib) return RES_BAD_ARG; if(!BXDF_TYPE_EQ(&bxdf->type, &ssf_microfacet_reflection)) return RES_BAD_ARG; microfacet = bxdf->data; - microfacet->reflectivity = reflectivity; - if(microfacet->fresnel != fresnel) { if(microfacet->fresnel) SSF(fresnel_ref_put(fresnel)); SSF(fresnel_ref_get(fresnel)); diff --git a/src/test_ssf_microfacet_reflection.c b/src/test_ssf_microfacet_reflection.c @@ -38,48 +38,39 @@ main(int argc, char** argv) mem_init_proxy_allocator(&allocator, &mem_default_allocator); CHECK(ssf_bxdf_create(&allocator, &ssf_microfacet_reflection, &bxdf), RES_OK); CHECK(ssf_bxdf_create(&allocator, &bxdf_dummy, &dummy), RES_OK); - CHECK(ssf_fresnel_create - (&allocator, &ssf_fresnel_dielectric_dielectric, &F), RES_OK); + CHECK(ssf_fresnel_create(&allocator, &ssf_fresnel_no_op, &F), RES_OK); CHECK(ssf_microfacet_distribution_create (&allocator, &ssf_beckmann_distribution, &D), RES_OK); - CHECK(ssf_beckmann_distribution_setup(D, 0.7), RES_OK); + CHECK(ssf_beckmann_distribution_setup(D, 0.9), RES_OK); - CHECK(ssf_fresnel_dielectric_dielectric_setup(F, 0.7, 1.3), RES_OK); - - CHECK(ssf_microfacet_reflection_setup(NULL, -1, NULL, NULL), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, -1, NULL, NULL), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, NULL, NULL), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, NULL, NULL), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(NULL, -1, F, NULL), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, -1, F, NULL), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, F, NULL), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, F, NULL), RES_BAD_ARG); - - CHECK(ssf_microfacet_reflection_setup(NULL, -1, NULL, D), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, -1, NULL, D), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, NULL, D), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, NULL, D), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(NULL, -1, F, D), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, -1, F, D), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, F, D), RES_BAD_ARG); - CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, F, D), RES_OK); + CHECK(ssf_microfacet_reflection_setup(NULL, NULL, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, NULL, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, F, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, F, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, NULL, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, NULL, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, F, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, F, D), RES_OK); /* Numerically evaluate rho */ d3(N, 0, 1, 0); - d3_normalize(wo, d3(wo, rand_canonic(), rand_canonic(), rand_canonic())); sum = sum_sqr = 0; + ran_hemisphere_cos(N, wo, NULL); FOR_EACH(i, 0, NSTEPS) { - const double u = rand_canonic(); - const double v = rand_canonic(); - const double R = ssf_bxdf_sample(bxdf, u, v, wo, N, wi, &pdf); - const double weight = R * d3_dot(wi, N) / pdf; + double R; + double weight; + ran_hemisphere_cos(N, wi, &pdf); + R = ssf_bxdf_eval(bxdf, wo, N, wi); + weight = R * d3_dot(wi, N) / pdf; sum += weight; sum_sqr += weight*weight; } + E = sum / (double)NSTEPS; V = sum_sqr / (double)NSTEPS - E*E; SE = sqrt(V/(double)NSTEPS); + printf("%g +/- %g\n", E, SE); CHECK(eq_eps(E, ssf_bxdf_rho(bxdf, wo, N), SE), 1); CHECK(ssf_bxdf_ref_put(bxdf), RES_OK); @@ -92,3 +83,4 @@ main(int argc, char** argv) CHECK(mem_allocated_size(), 0); return 0; } +