public virtual Spectrum Le(RayDifferential r) { return(Spectrum.Create(0.0)); }
public Spectrum Sample_f( Vector3D woWorld, out Vector3D wiWorld, Point2D u, out double pdf, out BxdfType sampledType, BxdfType type = BxdfType.All) { // ProfilePhase pp(Prof::BSDFSampling); // Choose which _BxDF_ to sample int matchingComps = NumComponents(type); if (matchingComps == 0) { pdf = 0.0; sampledType = BxdfType.None; wiWorld = new Vector3D(); return(Spectrum.Create(0.0)); } int comp = Math.Min(Convert.ToInt32(Math.Floor(u[0] * matchingComps)), matchingComps - 1); // Get _BxDF_ pointer for chosen component Bxdf bxdf = null; int count = comp; for (int i = 0; i < _nBxDFs; ++i) { if (_bxdfs[i].MatchesFlags(type) && count-- == 0) { bxdf = _bxdfs[i]; break; } } //CHECK(bxdf != nullptr); //VLOG(2) << "BSDF::Sample_f chose comp = " << comp << " / matching = " << // matchingComps << ", bxdf: " << bxdf->ToString(); // Remap _BxDF_ sample _u_ to $[0,1)^2$ Point2D uRemapped = new Point2D(Math.Min(u[0] * matchingComps - comp, PbrtMath.OneMinusEpsilon), u[1]); // Sample chosen _BxDF_ Vector3D wi, wo = WorldToLocal(woWorld); if (wo.Z == 0) { wiWorld = new Vector3D(); pdf = 0.0; sampledType = BxdfType.None; return(Spectrum.Create(0.0)); } pdf = 0.0; sampledType = bxdf.Type; Spectrum f = bxdf.Sample_f(wo, out wi, uRemapped, out pdf, out sampledType); //VLOG(2) << "For wo = " << wo << ", sampled f = " << f << ", pdf = " // << *pdf << ", ratio = " << ((*pdf > 0) ? (f / *pdf) : Spectrum(0.)) // << ", wi = " << wi; if (pdf == 0.0) { sampledType = BxdfType.None; wiWorld = new Vector3D(); return(Spectrum.Create(0.0)); } wiWorld = LocalToWorld(wi); // Compute overall PDF with all matching _BxDF_s if ((bxdf.Type & BxdfType.Specular) != BxdfType.Specular && matchingComps > 1) { for (int i = 0; i < _nBxDFs; ++i) { if (_bxdfs[i] != bxdf && _bxdfs[i].MatchesFlags(type)) { pdf += _bxdfs[i].Pdf(wo, wi); } } } if (matchingComps > 1) { pdf /= matchingComps; } // Compute value of BSDF for sampled direction if ((bxdf.Type & BxdfType.Specular) != BxdfType.Specular) { bool reflect = wiWorld.Dot(_ng) * woWorld.Dot(_ng) > 0.0; f = Spectrum.Create(0.0); for (int i = 0; i < _nBxDFs; ++i) { if (_bxdfs[i].MatchesFlags(type) && ((reflect && ((_bxdfs[i].Type & BxdfType.Reflection) == BxdfType.Reflection) || (!reflect && ((_bxdfs[i].Type & BxdfType.Transmission) == BxdfType.Transmission))))) { f += _bxdfs[i].f(wo, wi); } } } //VLOG(2) << "Overall f = " << f << ", pdf = " << *pdf << ", ratio = " // << ((*pdf > 0) ? (f / *pdf) : Spectrum(0.)); return(f); }