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:
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;
}
+