@@ -134,14 +134,22 @@ DielectricBoth::eval(Imath::V3f wo, Imath::V3f wi) const
134134 if (cosMO <= 0 )
135135 return {};
136136 const float D = d.D (m);
137- // Reflection optimized density
138- const float D_refl_D = d.D_refl_D (wo, m);
139- const float D_refl = D_refl_D * D;
140- const float G1 = d.G1 (wo);
141- const Power F = f.eval (cosMO);
142- const float out = d.G2_G1 (wi, wo) * G1 / D_refl_D;
143- const float pdf = D_refl / (4 .0f * cosNO) * F[0 ];
144- return { wi, Power (out, 1 ), pdf, 0 };
137+ if constexpr (BSDLConfig::use_bvn_refraction) {
138+ // Reflection optimized density
139+ const float D_refl_D = d.D_refl_D (wo, m);
140+ const float D_refl = D_refl_D * D;
141+ const float G1 = d.G1 (wo);
142+ const Power F = f.eval (cosMO);
143+ const float out = d.G2_G1 (wi, wo) * G1 / D_refl_D;
144+ const float pdf = D_refl / (4 .0f * cosNO) * F[0 ];
145+ return { wi, Power (out, 1 ), pdf, 0 };
146+ } else {
147+ const float G1 = d.G1 (wo);
148+ const Power F = f.eval (cosMO);
149+ const float out = d.G2_G1 (wi, wo);
150+ const float pdf = (G1 * D * F[0 ]) / (4 .0f * cosNO);
151+ return { wi, Power (out, 1 ), pdf, 0 };
152+ }
145153 } else if (cosNI < 0 ) {
146154 // flip to same side as N
147155 const Imath::V3f Ht = (f.eta * wi + wo).normalized ()
@@ -155,15 +163,24 @@ DielectricBoth::eval(Imath::V3f wo, Imath::V3f wi) const
155163 if (Ht.z <= 0 || cosHO <= 0 || cosHI >= 0 || Ft <= 0 )
156164 return {};
157165 const float D = d.D (Ht);
158- // Reflection optimized density
159- const float D_refl_D = d.D_refl_D (wo, Ht);
160- const float D_refl = D_refl_D * D;
161- const float G1 = d.G1 (wo);
162- float J = (-cosHI * cosHO * SQR (f.eta ))
166+ float J = (-cosHI * cosHO * SQR (f.eta ))
163167 / (wo.z * SQR (cosHI * f.eta + cosHO));
164- float pdf = D_refl * J * Ft;
165- const float out = d.G2_G1 ({ wi.x , wi.y , -wi.z }, wo) * G1 / D_refl_D;
166- return { wi, Power (out, 1 ), pdf, 0 };
168+ if constexpr (BSDLConfig::use_bvn_refraction) {
169+ // Reflection optimized density
170+ const float D_refl_D = d.D_refl_D (wo, Ht);
171+ const float D_refl = D_refl_D * D;
172+ const float G1 = d.G1 (wo);
173+ float pdf = D_refl * J * Ft;
174+ const float out = d.G2_G1 ({ wi.x , wi.y , -wi.z }, wo) * G1
175+ / D_refl_D;
176+ return { wi, Power (out, 1 ), pdf, 0 };
177+ } else {
178+ const float G1 = d.G1 (wo);
179+ const float out = d.G2_G1 ({ wi.x , wi.y , -wi.z }, wo);
180+
181+ float pdf = J * G1 * D * Ft;
182+ return { wi, Power (out, 1 ), pdf, 0 };
183+ }
167184
168185 } else
169186 return {};
@@ -176,9 +193,13 @@ DielectricBoth::sample(Imath::V3f wo, float randu, float randv,
176193 // This skips micro normals not valid for reflection, but they
177194 // could be valid for refraction. Energy is ok because we renormalize
178195 // this lobe, but refraction will be biased for high roughness. We
179- // trade that for reduced noise.
180- const Imath::V3f m = d.sample_for_refl (wo, randu, randv);
181- const float cosMO = wo.dot (m);
196+ // trade that for reduced noise. We can disable BVN at compile time.
197+ Imath::V3f m;
198+ if constexpr (BSDLConfig::use_bvn_refraction)
199+ m = d.sample_for_refl (wo, randu, randv);
200+ else
201+ m = d.sample (wo, randu, randv);
202+ const float cosMO = wo.dot (m);
182203 if (cosMO <= 0 )
183204 return {};
184205 const float F = f.eval (cosMO)[0 ];
0 commit comments