public void SetShadingGeometry( Vector3D dpdu, Vector3D dpdv, Normal3D dndu, Normal3D dndv, bool orientationIsAuthoritative) { // Compute _shading.n_ for _SurfaceInteraction_ ShadingN = dpdu.Cross(dpdv).Normalize().ToNormal3D(); if (Shape != null && (Shape.ReverseOrientation ^ Shape.TransformSwapsHandedness)) { ShadingN = -ShadingN; } if (orientationIsAuthoritative) { N = N.FaceForward(ShadingN); } else { ShadingN = ShadingN.FaceForward(N); } // Initialize _shading_ partial derivative values ShadingDpdu = dpdu; ShadingDpdv = dpdv; ShadingDndu = dndu; ShadingDndv = dndv; }
public SurfaceInteraction( Point3D p, Vector3D pError, Point2D uv, Vector3D wo, Vector3D dpdu, Vector3D dpdv, Normal3D dndu, Normal3D dndv, double time, Shape shape, int faceIndex = 0) : base(p, (dpdu.Cross(dpdv).Normalize()).ToNormal3D(), pError, wo, time, null) { Uv = uv; Dpdu = dpdu; Dpdv = dpdv; Dndu = dndu; Dndv = dndv; Shape = shape; FaceIndex = faceIndex; ShadingN = N; ShadingDpdu = dpdu; ShadingDpdv = dpdv; ShadingDndu = dndu; ShadingDndv = dndv; // Adjust normal based on orientation and handedness if (shape != null && (shape.ReverseOrientation ^ shape.TransformSwapsHandedness)) { N *= -1; ShadingN *= -1; } }
public abstract Spectrum Sample_Le( Point2D u1, Point2D u2, double time, out Ray ray, out Normal3D nLight, out double pdfPos, out double pdfDir);
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); }
// 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 Interaction() { P = new Point3D(); Time = 0.0; PError = new Vector3D(); Wo = new Vector3D(); N = new Normal3D(); MediumInterface = null; }
public Interaction(Point3D p, double time, MediumInterface mediumInterface) { P = p; Time = time; MediumInterface = mediumInterface; Wo = new Vector3D(); PError = new Vector3D(); N = new Normal3D(); }
private static Ray3D ComputeIntersectionLine(ref Plane3D p1, ref Plane3D p2) { Ray3D ray = new Ray3D { Direction = (Vector3D)Normal3D.Cross(p1.Normal, p2.Normal) }; float num = ray.Direction.LengthSquared(); ray.Origin = (Point3D)(Vector3D.Cross((-p1.D * p2.Normal) + (p2.D * p1.Normal), ray.Direction) / num); return(ray); }
/// <inheritdoc /> public override Spectrum Li(RayDifferential ray, Scene scene, Sampler sampler, int depth = 0) { Spectrum L = Spectrum.Create(0.0); // Find closest ray intersection or return background radiance if (!scene.Intersect(ray, out SurfaceInteraction isect)) { foreach (var light in scene.Lights) { L += light.Le(ray); } return(L); } // Compute emitted and reflected light at ray intersection point // Initialize common variables for Whitted integrator Normal3D n = isect.ShadingN; Vector3D wo = isect.Wo; // Compute scattering functions for surface interaction isect.ComputeScatteringFunctions(ray); if (isect.Bsdf == null) { return(Li(new RayDifferential(isect.SpawnRay(ray.Direction)), scene, sampler, depth)); } // Compute emitted light if ray hit an area light source L += isect.Le(wo); // Add contribution of each light source foreach (var light in scene.Lights) { Spectrum Li = light.Sample_Li(isect, sampler.Get2D(), out Vector3D wi, out double pdf, out VisibilityTester visibility); if (Li.IsBlack() || pdf == 0.0) { continue; } Spectrum f = isect.Bsdf.f(wo, wi); if (!f.IsBlack() && visibility.Unoccluded(scene)) { L += f * Li * wi.AbsDot(n) / pdf; } } if (depth + 1 < _maxDepth) { // Trace rays for specular reflection and refraction L += SpecularReflect(ray, isect, scene, sampler, depth); L += SpecularTransmit(ray, isect, scene, sampler, depth); } return(L); }
public Normal3D Transform(Normal3D normal) { float x = normal.X; float y = normal.Y; float z = normal.Z; Matrix3D inverse = Inverse.Value; return new Normal3D( inverse.M11 * x + inverse.M21 * y + inverse.M31 * z, inverse.M12 * x + inverse.M22 * y + inverse.M32 * z, inverse.M13 * x + inverse.M23 * y + inverse.M33 * z); }
public Normal3D Transform(Normal3D normal) { float x = normal.X; float y = normal.Y; float z = normal.Z; Matrix3D inverse = Inverse.Value; return(new Normal3D( inverse.M11 * x + inverse.M21 * y + inverse.M31 * z, inverse.M12 * x + inverse.M22 * y + inverse.M32 * z, inverse.M13 * x + inverse.M23 * y + inverse.M33 * z)); }
public Interaction( Point3D p, Normal3D n, Vector3D pError, Vector3D wo, double time, MediumInterface mediumInterface) { P = p; N = n; PError = pError; Wo = wo; Time = time; MediumInterface = mediumInterface; }
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)); } }
/// <summary> /// Creates a new plane. /// </summary> /// <param name="normal">The normal vector of the plane.</param> /// <param name="d">The distance of the plane along its normal from the origin.</param> public Plane3D(Normal3D normal, float d) { Normal = normal; D = d; }
/// <summary> /// Points must be ordered CCW /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="c"></param> public Plane3D(Point3D a, Point3D b, Point3D c) { Normal = (Normal3D)Vector3D.Normalize(Vector3D.Cross(b - a, c - a)); D = Vector3D.Dot(Normal, (Vector3D)a); }
/// <summary> /// Points must be ordered CCW /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="c"></param> public Plane3D(Point3D a, Point3D b, Point3D c) { Normal = (Normal3D) Vector3D.Normalize(Vector3D.Cross(b - a, c - a)); D = Vector3D.Dot(Normal, (Vector3D) a); }
public abstract void Pdf_Le(Ray ray, Normal3D nLight, out double pdfPos, out double pdfDir);
public static Normal3D operator +(Normal3D n, Normal3D m) { Normal3D newVector = new Normal3D(n.x + m.x, n.y + m.y, n.z + m.z); return newVector; }