public override float Pdf(ref Vector wo, ref Vector wi, BxDFTypes bxDFType) { if(!SameHemisphere(ref wo, ref wi)) return 0f; return distr.Pdf(ref wo, ref wi); }
public RgbSpectrum rho(Vector wo, BxDFTypes flags) { RgbSpectrum ret = new RgbSpectrum(); for (int i = 0; i < bxdfs.Count; ++i) if (BxDF.MatchesFlags(bxdfs[i], flags)) ret += bxdfs[i].Rho(wo); return ret; }
public override float Pdf(ref Vector wo, ref Vector wi, BxDFTypes bxDFType) { return 1f; }
public float Pdf(ref Vector woW, ref Vector wiW, BxDFTypes flags) { if (bxdfs.Count == 0) return 0f; Vector wo = WorldToLocal(ref woW); var wi = WorldToLocal(ref wiW); float pdf = 0f; int matchingComps = 0; for (int i = 0; i < bxdfs.Count; ++i) if (BxDF.MatchesFlags(bxdfs[i], flags)) { ++matchingComps; pdf += bxdfs[i].Pdf(ref wo, ref wi); } return matchingComps > 0 ? pdf / matchingComps : 0f; }
public RgbSpectrum f(ref Vector woW, ref Vector wiW, BxDFTypes flags) { Vector wi = WorldToLocal(ref wiW); var wo = WorldToLocal(ref woW); if ((wiW & ng) * (woW & ng) > 0) // ignore BTDFs flags = flags & ~BxDFTypes.BSDF_TRANSMISSION; else // ignore BRDFs flags = flags & ~BxDFTypes.BSDF_REFLECTION; RgbSpectrum f = RgbSpectrum.ZeroSpectrum(); for (int i = 0; i < bxdfs.Count; ++i) if (BxDF.MatchesFlags(bxdfs[i], flags)) f += bxdfs[i].F(ref wo, ref wi); return f; }
public int NumComponents(BxDFTypes flags) { var res = bxdfs.Count(p => BxDF.MatchesFlags(p, flags)); return res; }
public RgbSpectrum Sample_f(ref Vector woW, out Vector wiW, float u1, float u2, float u3, out float pdf, out BxDFTypes? sampled, BxDFTypes flags = BxDFTypes.BSDF_ALL, BxDFTypes? sampledType = null) { BxDFTypes fl = flags; int matchingComps = NumComponents(fl); if (matchingComps == 0) { pdf = 0f; wiW = Vector.Zero; sampled = null; return new RgbSpectrum(0f); } int which = (int)Math.Min((u3 * matchingComps), matchingComps - 1); BxDF bxdf = null; int count = which; for (int i = 0; i < bxdfs.Count; ++i) if (BxDF.MatchesFlags(bxdfs[i], fl)) if (count-- == 0) { bxdf = bxdfs[i]; break; } Vector wi = new Vector(); Vector wo = WorldToLocal(ref woW); wiW = Vector.Zero; pdf = 0f; bool specularBounce; RgbSpectrum f = bxdf.Sample(ref wo, out wi, u1, u2, out pdf, out specularBounce); sampled = bxdf.Type; if (pdf > 0f && pdf < MathLab.Epsilon) return RgbSpectrum.ZeroSpectrum(); if (sampledType != null) sampledType = bxdf.Type; wiW = LocalToWorld(wi); if ((!BxDF.MatchesFlags(bxdf, BxDFTypes.BSDF_SPECULAR)) && matchingComps > 1) { for (int i = 0; i < bxdfs.Count; ++i) { if (bxdfs[i] != bxdf && BxDF.MatchesFlags(bxdfs[i], fl)) pdf += bxdfs[i].Pdf(ref wo, ref wi); } } if (matchingComps > 1) pdf /= matchingComps; // Compute value of BSDF for sampled direction if (BxDF.MatchesFlags(bxdf, BxDFTypes.BSDF_SPECULAR)) //if ((bxdf.Type & BxDFType.BSDF_SPECULAR) == 0) { f = RgbSpectrum.ZeroSpectrum(); if ((wiW & ng) * (woW & ng) > 0f) // ignore BTDFs { fl = fl & ~BxDFTypes.BSDF_TRANSMISSION; } else // ignore BRDFs fl = (fl & ~BxDFTypes.BSDF_REFLECTION); for (int i = 0; i < bxdfs.Count; ++i) if (BxDF.MatchesFlags(bxdfs[i], fl)) f += bxdfs[i].F(ref wo, ref wi); f = f / pdf; } return f; }
internal RgbSpectrum Sample_f(Vector wo, ref Vector wi, float bs1, float bs2, float bcs, out float bsdfPdf, BxDFTypes flags) { throw new NotImplementedException(); }
public static bool MatchesFlags(BxDF obj, BxDFTypes flags) { return (flags & obj.type).Equals(flags) || (flags & obj.type).Equals(obj.type); }
public BxDF(BxDFTypes t) { type = t; }
public override float Pdf(ref Vector wo, ref Vector wi, BxDFTypes bxDFType) { return mattePdf * mirrorPdf; }
public virtual float Pdf(ref Vector wo, ref Vector wi, BxDFTypes bxDFType) { return wi.z*MathLab.INVPI; }