Пример #1
0
        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;
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
 public abstract Spectrum Sample_Le(
     Point2D u1,
     Point2D u2,
     double time,
     out Ray ray,
     out Normal3D nLight,
     out double pdfPos,
     out double pdfDir);
Пример #4
0
        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);
        }
Пример #5
0
        // 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);
        }
Пример #6
0
 public Interaction()
 {
     P               = new Point3D();
     Time            = 0.0;
     PError          = new Vector3D();
     Wo              = new Vector3D();
     N               = new Normal3D();
     MediumInterface = null;
 }
Пример #7
0
 public Interaction(Point3D p, double time, MediumInterface mediumInterface)
 {
     P               = p;
     Time            = time;
     MediumInterface = mediumInterface;
     Wo              = new Vector3D();
     PError          = new Vector3D();
     N               = new Normal3D();
 }
Пример #8
0
        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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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));
        }
Пример #12
0
 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;
 }
Пример #13
0
        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));
            }
        }
Пример #14
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;
 }
Пример #15
0
 /// <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);
 }
Пример #16
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;
 }
Пример #17
0
 /// <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);
 }
Пример #18
0
 public abstract void Pdf_Le(Ray ray, Normal3D nLight, out double pdfPos, out double pdfDir);
Пример #19
0
 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;
 }