void test01_smoothTransmittance() { /* Smooth diffuse transmittance - compare polynomial approximations to ground truth */ for (int i=0; i<=10; ++i) { Float eta = 1 + i/10.0f; Float f1 = fresnelDiffuseReflectance(eta, false); Float f2 = fresnelDiffuseReflectance(eta, true); Float f3 = fresnelDiffuseReflectance(1/eta, false); Float f4 = fresnelDiffuseReflectance(1/eta, true); assertEqualsEpsilon(std::abs(f1-f2), (Float) 0, 1e-3f); assertEqualsEpsilon(std::abs(f3-f4), (Float) 0, 1e-3f); } }
Float *computeTransmittance(const char *name, Float ior, Float alpha, size_t resolution, Float &diffTrans, int inverted) { Properties bsdfProps(alpha == 0 ? "dielectric" : "roughdielectric"); if (inverted) { bsdfProps.setFloat("intIOR", 1.00); bsdfProps.setFloat("extIOR", ior); } else { bsdfProps.setFloat("extIOR", 1.00); bsdfProps.setFloat("intIOR", ior); } bsdfProps.setFloat("alpha", alpha); bsdfProps.setString("distribution", name); ref<BSDF> bsdf = static_cast<BSDF *>( PluginManager::getInstance()->createObject(bsdfProps)); Float stepSize = 1.0f / (resolution-1); Float error; NDIntegrator intTransmittance(1, 2, 50000, 0, 1e-6f); NDIntegrator intDiffTransmittance(1, 1, 50000, 0, 1e-6f); Float *transmittances = new Float[resolution]; for (size_t i=0; i<resolution; ++i) { Float t = i * stepSize; if (i == 0) /* Don't go all the way to zero */ t = stepSize/10; Float cosTheta = std::pow(t, (Float) 4.0f); Vector wi(std::sqrt(std::max((Float) 0, 1-cosTheta*cosTheta)), 0, cosTheta); Float min[2] = {0, 0}, max[2] = {1, 1}; intTransmittance.integrateVectorized( boost::bind(&transmittanceIntegrand, bsdf, wi, _1, _2, _3), min, max, &transmittances[i], &error, NULL); } Float min[1] = { 0 }, max[1] = { 1 }; intDiffTransmittance.integrateVectorized( boost::bind(&diffTransmittanceIntegrand, transmittances, resolution, _1, _2, _3), min, max, &diffTrans, &error, NULL); if (alpha == 0.0f) cout << diffTrans << " vs " << 1-fresnelDiffuseReflectance(inverted ? (1.0f / ior) : ior) << endl; return transmittances; }