public override Bsdf GetBsdf(DifferentialGeometry dgGeom, DifferentialGeometry dgShading) { // Allocate _BSDF_, possibly doing bump mapping with _bumpMap_ var dgs = (_bumpMap != null) ? Bump(_bumpMap, dgGeom, dgShading) : dgShading; var bsdf = new Bsdf(dgs, dgGeom.Normal); // Evaluate textures for _MatteMaterial_ material and allocate BRDF Spectrum r = Spectrum.Clamp(_kd.Evaluate(dgs)); float sig = MathUtility.Clamp(_sigma.Evaluate(dgs), 0.0f, 90.0f); if (!r.IsBlack) { if (sig == 0.0f) { bsdf.Add(new Lambertian(r)); } else { bsdf.Add(new OrenNayar(r, sig)); } } return(bsdf); }
public Spectrum SpecularTransmit( RayDifferential ray, SurfaceInteraction isect, Scene scene, Sampler sampler, int depth) { Vector3D wo = isect.Wo; double pdf; Point3D p = isect.P; Normal3D ns = isect.ShadingN; Bsdf bsdf = isect.Bsdf; Spectrum f = bsdf.Sample_f(wo, out Vector3D wi, sampler.Get2D(), out pdf, out BxdfType sampledType, BxdfType.Transmission | BxdfType.Specular); Spectrum L = Spectrum.Create(0.0); if (pdf > 0.0 && !f.IsBlack() && wi.AbsDot(ns) != 0.0) { // Compute ray differential _rd_ for specular transmission RayDifferential rd = new RayDifferential(isect.SpawnRay(wi)); if (ray.HasDifferentials) { rd.HasDifferentials = true; rd.RxOrigin = p + isect.Dpdx.ToPoint3D(); rd.RyOrigin = p + isect.Dpdy.ToPoint3D(); double eta = bsdf.Eta; Vector3D w = -wo; if (wo.Dot(ns) < 0.0) { eta = 1.0 / eta; } 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); double mu = eta * w.Dot(ns) - wi.Dot(ns); double dmudx = (eta - (eta * eta * w.Dot(ns)) / wi.Dot(ns)) * dDNdx; double dmudy = (eta - (eta * eta * w.Dot(ns)) / wi.Dot(ns)) * dDNdy; rd.RxDirection = wi + eta * dwodx - (mu * dndx + dmudx * ns).ToVector3D(); rd.RyDirection = wi + eta * dwody - (mu * dndy + dmudy * ns).ToVector3D(); } L = f * Li(rd, scene, sampler, depth + 1) * wi.AbsDot(ns) / pdf; } return(L); }
public static Spectrum SpecularTransmit(RayDifferential ray, Bsdf bsdf, Random rng, Intersection isect, Renderer renderer, Scene scene, Sample sample) { Vector wo = -ray.Direction, wi; float pdf; Point p = bsdf.DgShading.Point; Normal n = bsdf.DgShading.Normal; Spectrum f = bsdf.SampleF(wo, out wi, new BsdfSample(rng), out pdf, BxdfType.Transmission | BxdfType.Specular); Spectrum L = Spectrum.CreateBlack(); if (pdf > 0.0f && !f.IsBlack && Vector.AbsDot(wi, n) != 0.0f) { // Compute ray differential _rd_ for specular transmission var rd = new RayDifferential(p, wi, ray, isect.RayEpsilon); if (ray.HasDifferentials) { rd.HasDifferentials = true; rd.RxOrigin = p + isect.DifferentialGeometry.DpDx; rd.RyOrigin = p + isect.DifferentialGeometry.DpDy; float eta = bsdf.Eta; Vector w = -wo; if (Vector.Dot(wo, n) < 0) { eta = 1.0f / eta; } Normal dndx = bsdf.DgShading.DnDu * bsdf.DgShading.DuDx + bsdf.DgShading.DnDv * bsdf.DgShading.DvDx; Normal dndy = bsdf.DgShading.DnDu * bsdf.DgShading.DuDy + bsdf.DgShading.DnDv * bsdf.DgShading.DvDy; Vector dwodx = -ray.RxDirection - wo, dwody = -ray.RyDirection - wo; float dDNdx = Vector.Dot(dwodx, n) + Vector.Dot(wo, dndx); float dDNdy = Vector.Dot(dwody, n) + Vector.Dot(wo, dndy); float mu = eta * Vector.Dot(w, n) - Vector.Dot(wi, n); float dmudx = (eta - (eta * eta * Vector.Dot(w, n)) / Vector.Dot(wi, n)) * dDNdx; float dmudy = (eta - (eta * eta * Vector.Dot(w, n)) / Vector.Dot(wi, n)) * dDNdy; rd.RxDirection = wi + eta * dwodx - (Vector)(mu * dndx + dmudx * n); rd.RyDirection = wi + eta * dwody - (Vector)(mu * dndy + dmudy * n); } Spectrum Li = renderer.Li(scene, rd, sample, rng); L = f * Li * Vector.AbsDot(wi, n) / pdf; } return(L); }