public void ComputeScatteringFunctions(SurfaceInteraction si, IObjectArena arena, TransportMode mode, bool allowMultipleLobes) { var s1 = Scale.Evaluate(in si).Clamp(); var s2 = (Spectrum.One - s1).Clamp(); M1.ComputeScatteringFunctions(si, arena, mode, allowMultipleLobes); var si2 = arena.Create <SurfaceInteraction>().Initialize(in si); M2.ComputeScatteringFunctions(si2, arena, mode, allowMultipleLobes); var n1 = si.BSDF.NumberOfComponents(); var n2 = si2.BSDF.NumberOfComponents(); for (var i = 0; i < n1; ++i) { var collection = (IBxDFCollection)si.BSDF; var bxdf = arena.Create <ScaledBxDF>().Initialize(collection[i], s1); collection.Set(bxdf, i); } for (var i = 0; i < n2; ++i) { var collection = (IBxDFCollection)si2.BSDF; var bxdf = arena.Create <ScaledBxDF>().Initialize(collection[i], s2); collection.Set(bxdf, i); } }
public void ComputeScatteringFunctions(SurfaceInteraction si, IObjectArena arena, TransportMode mode, bool allowMultipleLobes) { BumpMap?.Bump(si); var bsdf = si.BSDF.Initialize(in si); var kd = Kd.Evaluate(in si).Clamp(); if (!kd.IsBlack()) { bsdf.Add(arena.Create <LambertianReflection>().Initialize(in kd)); } var ks = Ks.Evaluate(in si).Clamp(); if (ks.IsBlack()) { return; } var fresnel = arena.Create <FresnelDielectric>().Initialize(1.5f, 1f); var rough = Roughness.Evaluate(in si); if (RemapRoughness) { rough = TrowbridgeReitzDistribution.RoughnessToAlpha(rough); } var distribution = arena.Create <TrowbridgeReitzDistribution>().Initialize(rough, rough); bsdf.Add(arena.Create <MicrofacetReflection>().Initialize(ks, distribution, fresnel)); }
public void ComputeScatteringFunctions(SurfaceInteraction si, IObjectArena arena, TransportMode mode, bool allowMultipleLobes) { BumpMap?.Bump(si); var bsdf = si.BSDF.Initialize(in si); var r = Kd.Evaluate(in si).Clamp(); if (r.IsBlack()) { return; } var sig = Clamp(0, 90, Sigma.Evaluate(in si)); if (sig == 0f) { bsdf.Add(arena.Create <LambertianReflection>().Initialize(in r)); } else { bsdf.Add(arena.Create <OrenNayar>().Initialize(in r, sig)); } }
public bool IntersectTr(Ray ray, Sampler sampler, out SurfaceInteraction isect, out Spectrum transmittance) { transmittance = Spectrum.Create(1.0); while (true) { bool hitSurface = Intersect(ray, out isect); // Accumulate beam transmittance for ray segment if (ray.Medium != null) { transmittance *= ray.Medium.Tr(ray, sampler); } // Initialize next ray segment or terminate transmittance computation if (!hitSurface) { return(false); } if (isect.Primitive.GetMaterial() != null) { return(true); } ray = isect.SpawnRay(ray.Direction); } }
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 bool Intersect(ref Ray r, ref SurfaceInteraction si) { if (_nodes.Length == 0) { return(false); } var info = _info.Value.Initialize(in r); while (true) { var node = _nodes[info.CurrentNodeIndex]; if (node.Bounds.IntersectP(r, info.DirIsNegative)) { if (node.NPrimitives > 0) { for (var i = 0; i < node.NPrimitives; ++i) { if (_p[node.PrimitivesOffset + i].Intersect(ref r, ref si)) { info.Hit = true; } } if (info.ToVisitOffset == 0) { break; } info.CurrentNodeIndex = info.NodesToVisit[--info.ToVisitOffset]; } else { if (info.DirIsNegative[node.Axis] == 1) { info.NodesToVisit[info.ToVisitOffset++] = info.CurrentNodeIndex + 1; info.CurrentNodeIndex = node.SecondChildOffset; } else { info.NodesToVisit[info.ToVisitOffset++] = node.SecondChildOffset; info.CurrentNodeIndex += 1; } } } else { if (info.ToVisitOffset == 0) { break; } info.CurrentNodeIndex = info.NodesToVisit[--info.ToVisitOffset]; } } return(info.Hit); }
// BSDF Public Methods public Bsdf(SurfaceInteraction si, double eta = 1.0) { Eta = eta; _ns = si.ShadingN; _ng = si.N; _ss = si.ShadingDpdu.Normalize(); _ts = _ns.Cross(_ss); }
public void ComputeScatteringFunctions(SurfaceInteraction inter, bool allowMultipleLobes) { var r = Diffuse.Clamp(); //TODO sigma -> Oren-Nayar inter.Bsdf = new BSDF(inter); inter.Bsdf.Add(new LambertianReflection(r)); }
public void ComputeScatteringFunctions(SurfaceInteraction inter, bool allowMultipleLobes) { inter.Bsdf = new BSDF(inter); if (!Reflectance.IsBlack()) { inter.Bsdf.Add(new SpecularReflection(Reflectance, new FresnelNoOp())); } }
public override bool Intersect(Ray ray, out float tHit, out SurfaceInteraction inter) { tHit = 0f; inter = null; // Transform the ray from world space to object space var rayObj = WorldToObject * ray; // Compute intersections with the disk plane // // We want t such that h = o_z + t d_z // Hence t = (h - o_z) / d_z if (rayObj.D.Z == 0) { return(false); } tHit = (Height - rayObj.O.Z) / rayObj.D.Z; if (tHit <= 0 || tHit >= rayObj.Tmax) { return(false); } // Check if the intersection point lies in the circle var hitPos = rayObj.At(tHit); var dist2 = hitPos.X * hitPos.X + hitPos.Y * hitPos.Y; if (dist2 > Radius * Radius) { return(false); } // Refine the disk intersection point hitPos.Z = Height; // Compute the parametric representation of the intersection point var phi = Math.Atan2(hitPos.Y, hitPos.X); if (phi < 0) { phi += 2 * MathUtils.Pi; } var rHit = (float)Math.Sqrt(dist2); var dpdu = new Vector3 <float>(-MathUtils.TwoPi * hitPos.Y, MathUtils.TwoPi * hitPos.X, 0); var dpdv = new Vector3 <float>(hitPos.X, hitPos.Y, 0) * (-Radius / rHit); inter = ObjectToWorld * new SurfaceInteraction( hitPos, Vector3 <float> .Zero, Point2 <float> .Zero, -rayObj.D, dpdu, dpdv, Normal3 <float> .Zero, Normal3 <float> .Zero, rayObj.Time, this); return(true); }
public bool Intersect(ref Ray r, ref SurfaceInteraction si) { if (!Shape.Intersect(in r, out var tHit, ref si)) { return(false); } r.TMax = tHit; si.Primitive = this; // TODO: Handle medium. return(true); }
public override bool Intersect(Ray ray, out SurfaceInteraction inter) { var hit = false; inter = null; var invDir = new Vector3 <float>(1.0f / ray.D.X, 1.0f / ray.D.Y, 1.0f / ray.D.Z); bool[] dirIsNeg = { invDir.X < 0, invDir.Y < 0, invDir.Z < 0 }; int toVisitOffset = 0, currentNodeIndex = 0; int[] nodesToVisit = new int[64]; while (true) { var node = nodes[currentNodeIndex]; if (node.Bounds.IntersectP(ray, out float t0, out float t1)) { // Leaf node: intersect ray with primitives if (node.PrimitiveCount > 0) { for (var i = 0; i < node.PrimitiveCount; ++i) { if (allPrimitives[node.PrimitivesOffset + i].Intersect(ray, out inter)) { hit = true; } } if (toVisitOffset == 0) { break; } currentNodeIndex = nodesToVisit[--toVisitOffset]; } // Interior node: process children else { if (dirIsNeg[node.Axis]) { nodesToVisit[toVisitOffset++] = currentNodeIndex + 1; currentNodeIndex = node.SecondChildOffset; } else { nodesToVisit[toVisitOffset++] = node.SecondChildOffset; currentNodeIndex = currentNodeIndex + 1; } } }
protected void ProcessCollisions() { SurfaceInteraction newInteraction = SurfaceInteraction; var nulos = Collisions.Where(c => c.Key == null).ToArray(); foreach (var nulo in nulos) { Collisions.Remove(nulo.Key); } if (Collisions.Count > 0) { float minAngle = float.MaxValue; foreach (Collision collision in Collisions.Values) { foreach (ContactPoint contact in collision.contacts) { float angle = Vector3.Angle(contact.normal, Vector3.up); if (angle < minAngle) { minAngle = angle; Surface = contact; } } } if (minAngle >= 90F) { newInteraction = SurfaceInteraction.Floating; } else if (minAngle > slopeAngle) { newInteraction = SurfaceInteraction.Sliding; } else { newInteraction = SurfaceInteraction.Grounded; } } else { newInteraction = SurfaceInteraction.Floating; } if (newInteraction != SurfaceInteraction) { SurfaceInteraction = newInteraction; } }
public void ComputeScatteringFunctions(SurfaceInteraction si, IObjectArena arena, TransportMode mode, bool allowMultipleLobes) { _bumpMap?.Bump(si); si.BSDF.Initialize(si); var R = _kr.Evaluate(si).Clamp(); if (!R.IsBlack()) { si.BSDF.Add(arena.Create <SpecularReflection>().Initialize(R, arena.Create <FresnelNoOp>())); } }
public override (Spectrum, Vector3, double, Vector3) Sample_Li(SurfaceInteraction source) { (SurfaceInteraction pShape, double pdf) = sphere.Sample(source); if (pdf == 0 || (pShape.Point - source.Point).LengthSquared() < Renderer.Epsilon) { return(Spectrum.ZeroSpectrum, Vector3.ZeroVector, 0, Vector3.ZeroVector); } var wi = (pShape.Point - source.Point).Normalize(); var Li = L(pShape, -wi); return(Li, wi, pdf, pShape.Point); }
public void ComputeScatteringFunctions(SurfaceInteraction inter, bool allowMultipleLobes) { inter.Bsdf = new BSDF(inter); if (!diffuse.IsBlack()) { inter.Bsdf.Add(new LambertianReflection(diffuse)); } if (!specular.IsBlack()) { var fresnel = new FresnelDielectric(1.5f, 1.0f); var distribution = new TrowbridgeReitzDistribution(roughness); inter.Bsdf.Add(new MicrofacetReflection(specular, distribution, fresnel)); } }
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)); } }
private Spectrum SpecularReflect(RayDifferential ray, SurfaceInteraction inter, Scene scene, Camera camera, Sampler sampler, int depth) { // Sample a direction with the BSDF var type = BxDFType.Reflection | BxDFType.Specular; var f = inter.Bsdf.Sample_f(inter.Wo, out Vector3 <float> wi, sampler.Get2D(), out float pdf, type, out BxDF.BxDFType sampledType); // Add the contribution of this reflection if (pdf > 0 && !f.IsBlack() && Vector3 <float> .AbsDot(wi, inter.Shading.N) != 0) { var newRay = inter.SpawnRay(wi).ToDiff(); if (ray.HasDifferentials) { // TODO } return(f * Li(newRay, scene, camera, sampler, depth + 1) * Vector3 <float> .AbsDot(wi, inter.Shading.N) * (1.0f / pdf)); } return(Spectrum.Zero); }
public static void Bump(this ITexture2 <float> d, SurfaceInteraction si) { var displace = d.Evaluate(si); var du = 0.5f * Abs(si.Dudx) + Abs(si.Dudy); // Create small du if no differential available. if (du == 0f) { du = 0.0005f; } si.P += du * si.ShadingGeometry.Dpdu; si.UV += new Vector2(du, 0f); si.N = ((Normal)Vector.Cross(si.ShadingGeometry.Dpdu, si.ShadingGeometry.Dpdv) + du * si.Dndu).Normalize(); var uDisplace = d.Evaluate(si); var dv = 0.5f * Abs(si.Dvdx) + Abs(si.Dvdy); // Create small dv if no differential available. if (dv == 0f) { dv = 0.0005f; } si.P += dv * si.ShadingGeometry.Dpdv; si.UV += new Vector2(0f, dv); si.N = ((Normal)Vector.Cross(si.ShadingGeometry.Dpdu, si.ShadingGeometry.Dpdv) + dv * si.Dndv).Normalize(); var vDisplace = d.Evaluate(si); var dpdu = si.ShadingGeometry.Dpdu + (uDisplace - displace) / du * (Vector)si.ShadingGeometry.N + displace * (Vector)si.ShadingGeometry.Dndu; var dpdv = si.ShadingGeometry.Dpdv + (vDisplace - displace) / dv * (Vector)si.ShadingGeometry.N + displace * (Vector)si.ShadingGeometry.Dndv; si.SetShadingGeometry(dpdu, dpdv, si.ShadingGeometry.Dndu, si.ShadingGeometry.Dndv, false); }
public void ComputeScatteringFunctions(SurfaceInteraction si, IObjectArena arena, TransportMode mode, bool allowMultipleLobes) { _bumpMap?.Bump(si); si.BSDF.Initialize(si); var uRough = _uRoughness?.Evaluate(si) ?? _roughness.Evaluate(si); var vRough = _vRoughness?.Evaluate(si) ?? _roughness.Evaluate(si); if (_remapRoughness) { uRough = TrowbridgeReitzDistribution.RoughnessToAlpha(uRough); vRough = TrowbridgeReitzDistribution.RoughnessToAlpha(vRough); } var fr = arena.Create <FresnelConductor>().Initialize(Spectrum.One, _eta.Evaluate(si), _k.Evaluate(si)); var dist = arena.Create <TrowbridgeReitzDistribution>().Initialize(uRough, vRough); si.BSDF.Add(arena.Create <MicrofacetReflection>().Initialize(Spectrum.One, dist, fr)); }
/// <inheritdoc /> public override void ComputeScatteringFunctions(SurfaceInteraction isect, TransportMode mode, bool allowMultipleLobes) { throw new InvalidOperationException("Aggregate.ComputeScatteringFunctions() method called; should have gone to GeometricPrimitive"); }
public abstract bool Intersect( Ray ray, out double tHit, out SurfaceInteraction isect, bool testAlphaTexture = true);
public void ComputeScatteringFunctions(SurfaceInteraction si, IObjectArena arena, TransportMode mode, bool allowMultipleLobes) { BumpMap?.Bump(si); si.BSDF.Initialize(si); // Diffuse var c = Color.Evaluate(si).Clamp(); var metallicWeight = Metallic.Evaluate(si); var e = Eta.Evaluate(si); var strans = SpecTrans.Evaluate(si); var diffuseWeight = (1f - metallicWeight) * (1f - strans); var dt = DiffTrans.Evaluate(si) / 2f; var rough = Roughness.Evaluate(si); var lum = c.YComponent(); var Ctint = lum > 0f ? c / lum : Spectrum.One; if (diffuseWeight > 0f) { if (IsThin) { var flat = Flatness.Evaluate(si); si.BSDF.Add(arena.Create <DisneyDiffuse>().Initialize(diffuseWeight * (1f - flat) * (1 - dt) * c)); si.BSDF.Add(arena.Create <DisneyFakeSS>().Initialize(diffuseWeight * flat * (1f - dt) * c, rough)); } else { var sd = ScatterDistance.Evaluate(si); if (sd.IsBlack()) { si.BSDF.Add(arena.Create <DisneyDiffuse>().Initialize(diffuseWeight * c)); } else { // The line below was the original code but produces some odd results. si.BSDF.Add(arena.Create <SpecularTransmission>().Initialize(Spectrum.One, 1f, e, mode)); si.BSSRDF = arena.Create <DisneyBSSRDF>().Initialize(diffuseWeight * c, sd, si, e, this, mode); } } // Retro-reflection. si.BSDF.Add(arena.Create <DisneyRetro>().Initialize(diffuseWeight * c, rough)); // Sheen var sheenWeight = Sheen.Evaluate(si); if (sheenWeight > 0f) { var stint = SheenTint.Evaluate(si); var Csheen = Spectrum.Lerp(Spectrum.One, Ctint, stint); si.BSDF.Add(arena.Create <DisneySheen>().Initialize(diffuseWeight * sheenWeight * Csheen)); } } // Microfacet distribution var aspect = Sqrt(1f - Anisotropic.Evaluate(si) * 0.9f); var ax = Max(0.001f, Sqr(rough) / aspect); var ay = Max(0.001f, Sqr(rough) * aspect); var dist = arena.Create <DisneyMicrofacetDistribution>().Initialize(ax, ay); // Specular = Trowbridge-Reitz with modified Fresnel function. var specTint = SpecularTint.Evaluate(si); var Cspec0 = Spectrum.Lerp(SchlickR0FromEta(e) * Spectrum.Lerp(Spectrum.One, Ctint, specTint), c, metallicWeight); var fresnel = arena.Create <DisneyFresnel>().Initialize(Cspec0, metallicWeight, e); si.BSDF.Add(arena.Create <MicrofacetReflection>().Initialize(c, dist, fresnel)); // Clearcoat var cc = Clearcoat.Evaluate(si); if (cc > 0f) { si.BSDF.Add(arena.Create <DisneyClearcoat>() .Initialize(cc, Lerp(0.1f, 0.001f, ClearcoatGloss.Evaluate(si)))); } // BTDF if (strans > 0f) { // Walter et al's model, with the provided transmissive term scaled // by sqrt(color), so that after two refractions, we're back to the // provided color. var T = strans * c.Sqrt(); if (IsThin) { var rScaled = (0.65f * e - 0.35f) * rough; var atx = Max(0.001f, Sqr(rScaled) / aspect); var aty = Max(0.001f, Sqr(rScaled) * aspect); var scaledDist = arena.Create <TrowbridgeReitzDistribution>().Initialize(atx, aty); si.BSDF.Add(arena.Create <MicrofacetTransmission>().Initialize(T, scaledDist, 1f, e, mode)); } else { si.BSDF.Add(arena.Create <MicrofacetTransmission>().Initialize(T, dist, 1f, e, mode)); } } if (IsThin) { si.BSDF.Add(arena.Create <LambertianTransmission>().Initialize(dt * c)); } }
public override double Pdf_Li(SurfaceInteraction si, Vector3 wi) { return(sphere.Pdf(si, wi)); }
public void ComputeScatteringFunctions(SurfaceInteraction surfaceInteraction, IObjectArena arena, TransportMode mode, in bool allowMultipleLobes)
public override bool Intersect(Ray ray, out float t, out SurfaceInteraction inter) { t = 0.0f; inter = null; // Transform the ray from world space to object space var rayObj = WorldToObject * ray; // The implicit representation of the sphere is: // // x² + y² + z² - r² = 0 // // Subtituting the parametric representation of the ray: // // (ox + t dx)² + (oy + t dy)² + (oz + t dz)² = r² // // Or, with the following coefficients: // // a t² + b t + c = 0 var a = rayObj.D.X * rayObj.D.X + rayObj.D.Y * rayObj.D.Y + rayObj.D.Z * rayObj.D.Z; var b = 2 * (rayObj.D.X * rayObj.O.X + rayObj.D.Y * rayObj.O.Y + rayObj.D.Z * rayObj.O.Z); var c = rayObj.O.X * rayObj.O.X + rayObj.O.Y * rayObj.O.Y + rayObj.O.Z * rayObj.O.Z - Radius * Radius; // Solve the quadration equation for t if (!MathUtils.Quadratic(a, b, c, out float t0, out float t1)) { return(false); } // Look for the nearest intersection if (t0 > rayObj.Tmax || t1 <= 0) { return(false); } float tHit = t0; if (tHit <= 0) { tHit = t1; if (tHit > rayObj.Tmax) { return(false); } } t = tHit; // Initialize the interaction parameters var hitPos = rayObj.At(tHit); var hitPhi = MathF.Atan2(hitPos.Y, hitPos.X); // Transform the hit point to polar coordinates if (hitPhi < 0) { hitPhi += 2 * MathF.PI; } var theta = MathF.Acos(MathUtils.Clamp(hitPos.Z / Radius, -1, 1)); //var u = hitPhi / (2 * Math.PI); //var v = theta / Math.PI; var zRadius = MathF.Sqrt(hitPos.X * hitPos.X + hitPos.Y * hitPos.Y); var invZRadius = 1.0f / zRadius; var cosPhi = hitPos.X * invZRadius; var sinPhi = hitPos.Y * invZRadius; var dpdu = new Vector3 <float>(-MathUtils.TwoPi * hitPos.Y, MathUtils.TwoPi * hitPos.X, 0); var dpdv = new Vector3 <float>(hitPos.Z * cosPhi, hitPos.Z * sinPhi, -Radius * MathF.Sin(theta)) * -MathUtils.Pi; inter = ObjectToWorld * new SurfaceInteraction( hitPos, Vector3 <float> .Zero, Point2 <float> .Zero, -rayObj.D, dpdu, dpdv, Normal3 <float> .Zero, Normal3 <float> .Zero, rayObj.Time, this); return(true); }
public abstract bool Intersect(Ray r, out SurfaceInteraction isect);
public bool Intersect(Ray ray, out SurfaceInteraction isect) { // ++nIntersectionTests; // DCHECK_NE(ray.d, Vector3f(0, 0, 0)); return(_aggregate.Intersect(ray, out isect)); }
/// <inheritdoc /> public override bool Intersect(Ray ray, out SurfaceInteraction isect) { isect = null; if (nodes == null) { return(false); } //ProfilePhase p(Prof::AccelIntersect); bool hit = false; Vector3D invDir = new Vector3D(1.0 / ray.Direction.X, 1.0 / ray.Direction.Y, 1.0 / ray.Direction.Z); bool[] dirIsNeg = new bool[3] { invDir.X < 0, invDir.Y < 0, invDir.Z < 0 }; // Follow ray through BVH nodes to find primitive intersections int toVisitOffset = 0, currentNodeIndex = 0; int[] nodesToVisit = new int[64]; while (true) { LinearBVHNode node = nodes[currentNodeIndex]; // Check ray against BVH node if (node.bounds.IntersectP(ray, invDir, dirIsNeg)) { if (node.nPrimitives > 0) { // Intersect ray with primitives in leaf BVH node for (int i = 0; i < node.nPrimitives; ++i) { if (primitives[node.primitivesOffset + i].Intersect( ray, out isect)) { hit = true; } } if (toVisitOffset == 0) { break; } currentNodeIndex = nodesToVisit[--toVisitOffset]; } else { // Put far BVH node on _nodesToVisit_ stack, advance to near // node if (dirIsNeg[node.axis]) { nodesToVisit[toVisitOffset++] = currentNodeIndex + 1; currentNodeIndex = node.secondChildOffset; } else { nodesToVisit[toVisitOffset++] = node.secondChildOffset; currentNodeIndex = currentNodeIndex + 1; } } } else { if (toVisitOffset == 0) { break; } currentNodeIndex = nodesToVisit[--toVisitOffset]; } } return(hit); }
public abstract void ComputeScatteringFunctions( SurfaceInteraction isect, TransportMode mode, bool allowMultipleLobes);