public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample, out float pdf, BxdfType flags = BxdfType.All) { BxdfType sampledType; return(SampleF(woW, out wiW, bsdfSample, out pdf, out sampledType, flags)); }
public double Pdf(Vector3D woWorld, Vector3D wiWorld, BxdfType flags = BxdfType.All) { //ProfilePhase pp(Prof::BSDFPdf); if (_nBxDFs == 0) { return(0.0); } Vector3D wo = WorldToLocal(woWorld); Vector3D wi = WorldToLocal(wiWorld); if (wo.Z == 0.0) { return(0.0); } double pdf = 0.0; int matchingComps = 0; for (int i = 0; i < _nBxDFs; ++i) { if (_bxdfs[i].MatchesFlags(flags)) { ++matchingComps; pdf += _bxdfs[i].Pdf(wo, wi); } } double v = matchingComps > 0 ? pdf / matchingComps : 0.0; return(v); }
public Spectrum f(Vector3D woW, Vector3D wiW, BxdfType flags = BxdfType.All) { // ProfilePhase pp(Prof::BSDFEvaluation); Vector3D wi = WorldToLocal(wiW), wo = WorldToLocal(woW); if (wo.Z == 0.0) { return(Spectrum.Create(0.0)); } bool reflect = wiW.Dot(_ng) * woW.Dot(_ng) > 0.0; Spectrum f = Spectrum.Create(0.0); for (int i = 0; i < _nBxDFs; ++i) { if (_bxdfs[i].MatchesFlags(flags) && ((reflect && ((_bxdfs[i].Type & BxdfType.Reflection) == BxdfType.Reflection)) || (!reflect && ((_bxdfs[i].Type & BxdfType.Transmission) == BxdfType.Transmission)))) { f += _bxdfs[i].f(wo, wi); } } return(f); }
public int NumComponents(BxdfType flags = BxdfType.All) { int num = 0; for (int i = 0; i < _nBxDFs; ++i) { if (_bxdfs[i].MatchesFlags(flags)) { ++num; } } return(num); }
public Spectrum Rho(Vector wo, Random rng, BxdfType flags = BxdfType.All, int sqrtSamples = 6) { int nSamples = sqrtSamples * sqrtSamples; var s1 = new float[2 * nSamples]; SamplingUtilities.StratifiedSample2D(s1, sqrtSamples, sqrtSamples, rng); Spectrum ret = Spectrum.CreateBlack(); foreach (var bxdf in _bxdfs) { if (bxdf.MatchesFlags(flags)) { ret += bxdf.Rho(wo, nSamples, s1); } } return(ret); }
public Spectrum SpecularReflect( RayDifferential ray, SurfaceInteraction isect, Scene scene, Sampler sampler, int depth) { // Compute specular reflection direction _wi_ and BSDF value Vector3D wo = isect.Wo; BxdfType type = BxdfType.Reflection | BxdfType.Specular; Spectrum f = isect.Bsdf.Sample_f(wo, out Vector3D wi, sampler.Get2D(), out double pdf, out BxdfType sampledType, type); // Return contribution of specular reflection Normal3D ns = isect.ShadingN; if (pdf > 0.0 && !f.IsBlack() && wi.AbsDot(ns) != 0.0) { // Compute ray differential _rd_ for specular reflection RayDifferential rd = new RayDifferential(isect.SpawnRay(wi)); if (ray.HasDifferentials) { rd.HasDifferentials = true; rd.RxOrigin = isect.P + isect.Dpdx.ToPoint3D(); rd.RyOrigin = isect.P + isect.Dpdy.ToPoint3D(); // Compute differential reflected directions Normal3D dndx = isect.ShadingDndu * isect.Dudx + isect.ShadingDndv * isect.Dvdx; Normal3D dndy = isect.ShadingDndu * isect.Dudy + isect.ShadingDndv * isect.Dvdy; Vector3D dwodx = -ray.RxDirection - wo, dwody = -ray.RyDirection - wo; double dDNdx = dwodx.Dot(ns) + wo.Dot(dndx); double dDNdy = dwody.Dot(ns) + wo.Dot(dndy); rd.RxDirection = wi - dwodx + 2.0 * (wo.Dot(ns) * dndx + dDNdx * ns).ToVector3D(); rd.RyDirection = wi - dwody + 2.0 * (wo.Dot(ns) * dndy + dDNdy * ns).ToVector3D(); } return(f * Li(rd, scene, sampler, depth + 1) * wi.AbsDot(ns) / pdf); } else { return(Spectrum.Create(0.0)); } }
public Spectrum rho( int nSamples, IEnumerable <Point2D> samples1, IEnumerable <Point2D> samples2, BxdfType flags = BxdfType.All) { Spectrum ret = Spectrum.Create(0.0); for (int i = 0; i < _nBxDFs; ++i) { if (_bxdfs[i].MatchesFlags(flags)) { ret += _bxdfs[i].rho(nSamples, samples1, samples2); } } return(ret); }
public virtual Spectrum Sample_f( Vector3D wo, out Vector3D wi, Point2D sample, out double pdf, out BxdfType sampledType) { sampledType = BxdfType.None; // Cosine-sample the hemisphere, flipping the direction if necessary wi = Sampling.CosineSampleHemisphere(sample); if (wo.Z < 0.0) { wi = new Vector3D(wi.X, wi.Y, -wi.Z); } pdf = Pdf(wo, wi); return(f(wo, wi)); }
public float Pdf(Vector woW, Vector wiW, BxdfType flags = BxdfType.All) { if (_bxdfs.Count == 0) { return(0.0f); } Vector wo = WorldToLocal(woW), wi = WorldToLocal(wiW); float pdf = 0.0f; int matchingComps = 0; foreach (var bxdf in _bxdfs) { if (bxdf.MatchesFlags(flags)) { ++matchingComps; pdf += bxdf.Pdf(wo, wi); } } float v = matchingComps > 0 ? pdf / matchingComps : 0.0f; return(v); }
public Spectrum F(Vector woW, Vector wiW, BxdfType flags = BxdfType.All) { Vector wi = WorldToLocal(wiW), wo = WorldToLocal(woW); if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs { flags &= ~BxdfType.Transmission; } else // ignore BRDFs { flags &= ~BxdfType.Reflection; } Spectrum f = Spectrum.CreateBlack(); foreach (var bxdf in _bxdfs) { if (bxdf.MatchesFlags(flags)) { f += bxdf.F(wo, wi); } } return(f); }
public float Pdf(Vector woW, Vector wiW, BxdfType flags = BxdfType.All) { if (_bxdfs.Count == 0) return 0.0f; Vector wo = WorldToLocal(woW), wi = WorldToLocal(wiW); float pdf = 0.0f; int matchingComps = 0; foreach (var bxdf in _bxdfs) if (bxdf.MatchesFlags(flags)) { ++matchingComps; pdf += bxdf.Pdf(wo, wi); } float v = matchingComps > 0 ? pdf / matchingComps : 0.0f; return v; }
public bool MatchesFlags(BxdfType t) { return((Type & t) == Type); }
protected Bxdf(BxdfType type) { Type = type; }
public Spectrum F(Vector woW, Vector wiW, BxdfType flags = BxdfType.All) { Vector wi = WorldToLocal(wiW), wo = WorldToLocal(woW); if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs flags &= ~BxdfType.Transmission; else // ignore BRDFs flags &= ~BxdfType.Reflection; Spectrum f = Spectrum.CreateBlack(); foreach (var bxdf in _bxdfs) if (bxdf.MatchesFlags(flags)) f += bxdf.F(wo, wi); return f; }
public bool MatchesFlags(BxdfType flags) { return((Type & flags) == Type); }
public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample, out float pdf, out BxdfType sampledType, BxdfType flags = BxdfType.All) { // Choose which _BxDF_ to sample int matchingComps = NumComponents(flags); if (matchingComps == 0) { wiW = Vector.Zero; pdf = 0.0f; sampledType = 0; return(Spectrum.CreateBlack()); } int which = Math.Min( MathUtility.Floor(bsdfSample.UComponent * matchingComps), matchingComps - 1); Bxdf bxdf = null; int count = which; foreach (var eachBxdf in _bxdfs) { if (eachBxdf.MatchesFlags(flags) && count-- == 0) { bxdf = eachBxdf; break; } } Debug.Assert(bxdf != null); // Sample chosen _BxDF_ Vector wo = WorldToLocal(woW); Vector wi; pdf = 0.0f; Spectrum f = bxdf.SampleF(wo, out wi, bsdfSample.UDir0, bsdfSample.UDir1, out pdf); if (pdf == 0.0f) { wiW = Vector.Zero; sampledType = 0; return(Spectrum.CreateBlack()); } sampledType = bxdf.Type; wiW = LocalToWorld(wi); // Compute overall PDF with all matching _BxDF_s if (!bxdf.Type.HasFlag(BxdfType.Specular) && matchingComps > 1) { foreach (var eachBxdf in _bxdfs) { if (eachBxdf != bxdf && eachBxdf.MatchesFlags(flags)) { pdf += bxdf.Pdf(wo, wi); } } } if (matchingComps > 1) { pdf /= matchingComps; } // Compute value of BSDF for sampled direction if (!bxdf.Type.HasFlag(BxdfType.Specular)) { f = Spectrum.CreateBlack(); if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs { flags &= ~BxdfType.Transmission; } else // ignore BRDFs { flags &= ~BxdfType.Reflection; } foreach (var eachBxdf in _bxdfs) { if (eachBxdf.MatchesFlags(flags)) { f += eachBxdf.F(wo, wi); } } } return(f); }
public Spectrum Rho(Vector wo, Random rng, BxdfType flags = BxdfType.All, int sqrtSamples = 6) { int nSamples = sqrtSamples * sqrtSamples; var s1 = new float[2 * nSamples]; SamplingUtilities.StratifiedSample2D(s1, sqrtSamples, sqrtSamples, rng); Spectrum ret = Spectrum.CreateBlack(); foreach (var bxdf in _bxdfs) if (bxdf.MatchesFlags(flags)) ret += bxdf.Rho(wo, nSamples, s1); return ret; }
public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample, out float pdf, BxdfType flags = BxdfType.All) { BxdfType sampledType; return SampleF(woW, out wiW, bsdfSample, out pdf, out sampledType, flags); }
public int NumComponents(BxdfType flags) { return(_bxdfs.Count(x => x.MatchesFlags(flags))); }
public int NumComponents(BxdfType flags) { return _bxdfs.Count(x => x.MatchesFlags(flags)); }
public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample, out float pdf, out BxdfType sampledType, BxdfType flags = BxdfType.All) { // Choose which _BxDF_ to sample int matchingComps = NumComponents(flags); if (matchingComps == 0) { wiW = Vector.Zero; pdf = 0.0f; sampledType = 0; return Spectrum.CreateBlack(); } int which = Math.Min( MathUtility.Floor(bsdfSample.UComponent * matchingComps), matchingComps - 1); Bxdf bxdf = null; int count = which; foreach (var eachBxdf in _bxdfs) if (eachBxdf.MatchesFlags(flags) && count-- == 0) { bxdf = eachBxdf; break; } Debug.Assert(bxdf != null); // Sample chosen _BxDF_ Vector wo = WorldToLocal(woW); Vector wi; pdf = 0.0f; Spectrum f = bxdf.SampleF(wo, out wi, bsdfSample.UDir0, bsdfSample.UDir1, out pdf); if (pdf == 0.0f) { wiW = Vector.Zero; sampledType = 0; return Spectrum.CreateBlack(); } sampledType = bxdf.Type; wiW = LocalToWorld(wi); // Compute overall PDF with all matching _BxDF_s if (!bxdf.Type.HasFlag(BxdfType.Specular) && matchingComps > 1) foreach (var eachBxdf in _bxdfs) if (eachBxdf != bxdf && eachBxdf.MatchesFlags(flags)) pdf += bxdf.Pdf(wo, wi); if (matchingComps > 1) pdf /= matchingComps; // Compute value of BSDF for sampled direction if (!bxdf.Type.HasFlag(BxdfType.Specular)) { f = Spectrum.CreateBlack(); if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs flags &= ~BxdfType.Transmission; else // ignore BRDFs flags &= ~BxdfType.Reflection; foreach (var eachBxdf in _bxdfs) if (eachBxdf.MatchesFlags(flags)) f += eachBxdf.F(wo, wi); } return f; }
public bool MatchesFlags(BxdfType flags) { return (Type & flags) == Type; }
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); }