Vec3f RoughPlasticBsdf::eval(const SurfaceScatterEvent &event) const { bool sampleR = event.requestedLobe.test(BsdfLobes::GlossyReflectionLobe); bool sampleT = event.requestedLobe.test(BsdfLobes::DiffuseReflectionLobe); if (!sampleR && !sampleT) return Vec3f(0.0f); if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f) return Vec3f(0.0f); Vec3f glossyR(0.0f); if (sampleR) glossyR = RoughDielectricBsdf::evalBase(event, true, false, (*_roughness)[*event.info].x(), _ior, _distribution); Vec3f diffuseR(0.0f); if (sampleT) { float eta = 1.0f/_ior; float Fi = Fresnel::dielectricReflectance(eta, event.wi.z()); float Fo = Fresnel::dielectricReflectance(eta, event.wo.z()); Vec3f diffuseAlbedo = albedo(event.info); diffuseR = ((1.0f - Fi)*(1.0f - Fo)*eta*eta*event.wo.z()*INV_PI)*(diffuseAlbedo/(1.0f - diffuseAlbedo*_diffuseFresnel)); if (_scaledSigmaA.max() > 0.0f) diffuseR *= std::exp(_scaledSigmaA*(-1.0f/event.wo.z() - 1.0f/event.wi.z())); } return glossyR + diffuseR; }
Vec3f RoughCoatBsdf::eval(const SurfaceScatterEvent &event) const { bool sampleR = event.requestedLobe.test(BsdfLobes::GlossyReflectionLobe); bool sampleT = event.requestedLobe.test(_substrate->lobes()); if (!sampleT && !sampleR) return Vec3f(0.0f); if (event.wi.z() <= 0.0f || event.wo.z() <= 0.0f) return Vec3f(0.0f); Vec3f glossyR(0.0f); if (sampleR) glossyR = RoughDielectricBsdf::evalBase(event, true, false, (*_roughness)[*event.info].x(), _ior, _distribution); Vec3f substrateR(0.0f); if (sampleT) { const Vec3f &wi = event.wi; const Vec3f &wo = event.wo; float eta = 1.0f/_ior; float cosThetaTi, cosThetaTo; float Fi = Fresnel::dielectricReflectance(eta, wi.z(), cosThetaTi); float Fo = Fresnel::dielectricReflectance(eta, wo.z(), cosThetaTo); if (Fi == 1.0f || Fo == 1.0f) return glossyR; Vec3f wiSubstrate(wi.x()*eta, wi.y()*eta, std::copysign(cosThetaTi, wi.z())); Vec3f woSubstrate(wo.x()*eta, wo.y()*eta, std::copysign(cosThetaTo, wo.z())); float compressionProjection = eta*eta*wo.z()/cosThetaTo; Vec3f substrateF = _substrate->eval(event.makeWarpedQuery(wiSubstrate, woSubstrate)); if (_scaledSigmaA.max() > 0.0f) substrateF *= std::exp(_scaledSigmaA*(-1.0f/cosThetaTo - 1.0f/cosThetaTi)); substrateR = compressionProjection*(1.0f - Fi)*(1.0f - Fo)*substrateF; } return glossyR + substrateR; }