// KdSubsurfaceMaterial Method Definitions void KdSubsurfaceMaterial::ComputeScatteringFunctions( SurfaceInteraction *si, MemoryArena &arena, TransportMode mode, bool allowMultipleLobes) const { // Perform bump mapping with _bumpMap_, if present if (bumpMap) Bump(bumpMap, si); si->bsdf = ARENA_ALLOC(arena, BSDF)(*si, eta); Spectrum R = Kr->Evaluate(*si).Clamp(); Spectrum T = Kt->Evaluate(*si).Clamp(); if (allowMultipleLobes && (!R.IsBlack() || !T.IsBlack())) si->bsdf->Add( ARENA_ALLOC(arena, FresnelSpecular)(1., 1., 1.f, eta, mode)); else { if (!R.IsBlack()) si->bsdf->Add(ARENA_ALLOC(arena, SpecularReflection)( R, ARENA_ALLOC(arena, FresnelDielectric)(1.f, eta))); if (!T.IsBlack()) si->bsdf->Add( ARENA_ALLOC(arena, SpecularTransmission)(T, 1.f, eta, mode)); } Spectrum sig_t = scale * sigma_t->Evaluate(*si).Clamp(); Spectrum kd = Kd->Evaluate(*si).Clamp(); Spectrum sig_a, sig_s; SubsurfaceFromDiffuse(table, kd, sig_t, &sig_a, &sig_s); si->bssrdf = ARENA_ALLOC(arena, TabulatedBSSRDF)(*si, this, mode, eta, sig_a, sig_s, table); }
BSSRDF *KdSubsurfaceMaterial::GetBSSRDF(const DifferentialGeometry &dgGeom, const DifferentialGeometry &dgShading, MemoryArena &arena) const { float ior = index->Evaluate(dgShading); float mfp = meanfreepath->Evaluate(dgShading); Spectrum kd = Kd->Evaluate(dgShading).Clamp(); Spectrum sigma_a, sigma_prime_s; SubsurfaceFromDiffuse(kd, mfp, ior, &sigma_a, &sigma_prime_s); return BSDF_ALLOC(arena, BSSRDF)(sigma_a, sigma_prime_s, ior); }
// KdSubsurfaceMaterial Method Definitions void KdSubsurfaceMaterial::ComputeScatteringFunctions( SurfaceInteraction *si, MemoryArena &arena, TransportMode mode, bool allowMultipleLobes) const { // Perform bump mapping with _bumpMap_, if present if (bumpMap) Bump(bumpMap, si); Spectrum R = Kr->Evaluate(*si).Clamp(); Spectrum T = Kt->Evaluate(*si).Clamp(); Float urough = uRoughness->Evaluate(*si); Float vrough = vRoughness->Evaluate(*si); // Initialize _bsdf_ for smooth or rough dielectric si->bsdf = ARENA_ALLOC(arena, BSDF)(*si, eta); if (R.IsBlack() && T.IsBlack()) return; bool isSpecular = urough == 0 && vrough == 0; if (isSpecular && allowMultipleLobes) { si->bsdf->Add( ARENA_ALLOC(arena, FresnelSpecular)(R, T, 1.f, eta, mode)); } else { if (remapRoughness) { urough = TrowbridgeReitzDistribution::RoughnessToAlpha(urough); vrough = TrowbridgeReitzDistribution::RoughnessToAlpha(vrough); } MicrofacetDistribution *distrib = isSpecular ? nullptr : ARENA_ALLOC(arena, TrowbridgeReitzDistribution)( urough, vrough); if (!R.IsBlack()) { Fresnel *fresnel = ARENA_ALLOC(arena, FresnelDielectric)(1.f, eta); if (isSpecular) si->bsdf->Add( ARENA_ALLOC(arena, SpecularReflection)(R, fresnel)); else si->bsdf->Add(ARENA_ALLOC(arena, MicrofacetReflection)( R, distrib, fresnel)); } if (!T.IsBlack()) { if (isSpecular) si->bsdf->Add(ARENA_ALLOC(arena, SpecularTransmission)( T, 1.f, eta, mode)); else si->bsdf->Add(ARENA_ALLOC(arena, MicrofacetTransmission)( T, distrib, 1.f, eta, mode)); } } Spectrum mfree = scale * mfp->Evaluate(*si).Clamp(); Spectrum kd = Kd->Evaluate(*si).Clamp(); Spectrum sig_a, sig_s; SubsurfaceFromDiffuse(table, kd, Spectrum(1.f) / mfree, &sig_a, &sig_s); si->bssrdf = ARENA_ALLOC(arena, TabulatedBSSRDF)(*si, this, mode, eta, sig_a, sig_s, table); }