Ejemplo n.º 1
0
Archivo: XYRect.cs Proyecto: basp/linie
        public bool TryIntersect(Ray ray, double tmin, double tmax, ref ShadeRecord sr)
        {
            var t = (this.k - ray.Origin.Z) / ray.Direction.Z;

            if (t < tmin || t > tmax)
            {
                return(false);
            }

            var x = ray.Origin.X + t * ray.Direction.X;
            var y = ray.Origin.Y + t * ray.Direction.Y;

            if (x < x0 || x > x1 || y < y0 || y > y1)
            {
                return(false);
            }

            var u = (x - x0) / (x1 - x0);
            var v = (y - y0) / (y1 - y0);
            var n = new Normal3(0, 0, 1);

            sr = new ShadeRecord
            {
                U        = u,
                V        = v,
                T        = t,
                Material = this.material,
                Point    = ray.GetPosition(t),
            };

            sr.SetFaceNormal(ray, n);
            return(true);
        }
Ejemplo n.º 2
0
Archivo: YZRect.cs Proyecto: basp/linie
        public bool TryIntersect(Ray ray, double tmin, double tmax, ref ShadeRecord sr)
        {
            var t = (this.k - ray.Origin.X) / ray.Direction.X;

            if (t < tmin || t > tmax)
            {
                return(false);
            }

            var y = ray.Origin.Y + t * ray.Direction.Y;
            var z = ray.Origin.Z + t * ray.Direction.Z;

            if (y < y0 || y > y1 || z < z0 || z > z1)
            {
                return(false);
            }

            var u = (y - y0) / (y1 - y0);
            var v = (z - z0) / (z1 - z0);
            var n = new Normal3(1, 0, 0);

            sr = new ShadeRecord
            {
                U        = u,
                V        = v,
                T        = t,
                Material = this.material,
                Point    = ray.GetPosition(t),
            };

            sr.SetFaceNormal(ray, n);
            return(true);
        }
Ejemplo n.º 3
0
        public Normal3 Sample(Random random)
        {
            ISphere sphere    = new UnitSphere(Position3.Origin);
            Normal3 direction = ((Direction3)sphere.SurfacePosition(random)).Normalized();

            return(IDirection3.InSameClosedHemisphere(Orientation, direction) ? direction : -direction);
        }
Ejemplo n.º 4
0
 public Interaction(Point3 <float> p, Normal3 <float> n, Vector3 <float> pError, Vector3 <float> wo, float time /*, MediumInterface medium*/)
 {
     P      = p;
     N      = n;
     PError = pError;
     Wo     = wo;
     Time   = time;
 }
Ejemplo n.º 5
0
        public void TestCtor()
        {
            var n = new Normal3(1, 2, 3);

            Assert.Equal(1, n.X);
            Assert.Equal(2, n.Y);
            Assert.Equal(3, n.Z);
        }
Ejemplo n.º 6
0
        public void TestExplicitVector4()
        {
            var     n = new Normal3(1, 2, 3);
            Vector4 u = (Vector4)n;

            Assert.True(u.IsDirection);
            Assert.Equal(1, u.X);
            Assert.Equal(2, u.Y);
            Assert.Equal(3, u.Z);
        }
Ejemplo n.º 7
0
        public BSDF(SurfaceInteraction inter, float eta = 1)
        {
            Eta = eta;

            ng = inter.N;
            ns = inter.Shading.N;

            ss = inter.Shading.DpDu.Normalized();
            ts = Vector3 <float> .Cross(ns.ToVector3(), ss);
        }
Ejemplo n.º 8
0
 /// <summary> Split this node </summary>
 /// <param name="split">The split to split this node with</param>
 protected virtual void Split(Split split)
 {
     Left           = new BoundingVolumeHierarchy(split.Left);
     Right          = new BoundingVolumeHierarchy(split.Right);
     SplitDirection = split.Direction;
     Items          = new HashSet <ISceneObject>()
     {
         Left, Right
     };
 }
Ejemplo n.º 9
0
Archivo: Utils.cs Proyecto: basp/linie
        public static Vector3 Refract(
            this Vector3 uv,
            Normal3 n,
            double etaiOverEtat)
        {
            var cosTheta     = Math.Min(Vector3.Dot(-uv, n), 1);
            var rOutPerp     = etaiOverEtat * (uv + cosTheta * n);
            var rOutParallel = -Math.Sqrt(
                Math.Abs(1.0 - Vector3.MagnitudeSquared(rOutPerp))) * n;

            return(rOutPerp + rOutParallel);
        }
Ejemplo n.º 10
0
 public void SplitPlanes()
 {
     for (int i = 0; i < 100; i++)
     {
         Normal3    direction = Normal3.UnitX;
         float      start     = (float)Utils.ThreadRandom.NextDouble();
         float      end       = (float)Utils.ThreadRandom.NextDouble();
         SpatialBin bin       = new(AxisAlignedPlane.X, start, end);
         Assert.AreEqual(direction * start, bin.SplitPlaneLeft.Position);
         Assert.AreEqual(direction, bin.SplitPlaneLeft.Normal);
         Assert.AreEqual(direction * end, bin.SplitPlaneRight.Position);
         Assert.AreEqual(-direction, bin.SplitPlaneRight.Normal);
     }
 }
Ejemplo n.º 11
0
        public Normal3 Sample(Random random)
        {
            /// Compute Height
            double theta = Math.Pow((random.NextDouble() - 0.5d) * Math.PI, Exponent);
            double r     = Math.Cos(theta);
            double w     = Math.Sin(theta);
            /// Compute u and v
            double angle = random.NextDouble() * 2 * Math.PI;
            double u     = r * Math.Cos(angle);
            double v     = r * Math.Sin(angle);
            /// Transform to Orientation
            Normal3 uDirection = Normal3.AnyPerpendicular(Orientation);
            Normal3 vDirection = Normal3.Perpendicular(Orientation, uDirection);

            return(new Normal3(uDirection * (float)u + vDirection * (float)v + Orientation * (float)w));
        }
Ejemplo n.º 12
0
        public void Sample()
        {
            Normal3 orientation   = Random.Shared.Normal3();
            var     distribution  = new HemisphericalDiffuse(orientation);
            int     samples       = 10_000;
            int     intervalCount = 10;

            int[] sampleCount = new int[intervalCount];
            for (int i = 0; i < samples; i++)
            {
                Normal3 sample = distribution.Sample(Random.Shared);
                double  dot    = Normal3.Similarity(orientation, sample);
                int     index  = (int)(dot * intervalCount);
                sampleCount[index]++;
            }
        }
Ejemplo n.º 13
0
        public Normal3 Sample(Random random)
        {
            /// Get Point uniformly on Disc
            double angle = random.NextDouble() * 2 * Math.PI;
            double r     = random.NextDouble() + random.NextDouble();

            r = r < 1 ? r : 2 - r;
            double u = r * Math.Cos(angle);
            double v = r * Math.Sin(angle);
            /// Raise Disc point to Hemisphere
            double  w          = Math.Sqrt(1 - u * u - v * v);
            Normal3 uDirection = Normal3.AnyPerpendicular(Orientation);
            Normal3 vDirection = Normal3.Perpendicular(Orientation, uDirection);

            return(new Normal3(uDirection * (float)u + vDirection * (float)v + Orientation * (float)w));
        }
Ejemplo n.º 14
0
        /// <summary> Get the best spatial binning split for a certain axis </summary>
        /// <param name="clipPlaneCreator">The direction the binning proces is going</param>
        /// <param name="axis">The axis selector</param>
        /// <returns>The best spatial binning split in the specified direction</returns>
        Split?BestSpatialBinSplit(Normal3 splitDirection, Func <bool, float, AxisAlignedPlane> clipPlaneCreator, Func <Vector3, float> axis)
        {
            float binStart      = axis(Shape.BoundingBox.MinCorner.Vector);
            float binEnd        = axis(Shape.BoundingBox.MaxCorner.Vector);
            float binSize       = axis(Shape.BoundingBox.Size.Vector) / SpatialBinAmount;
            float k1            = SpatialBinAmount * BinningEpsilon / axis(Shape.BoundingBox.Size.Vector);
            float bestSplitCost = SurfaceAreaHeuristic(Items.Count, Shape.BoundingBox.SurfaceArea);
            Split?bestSplit     = null;

            for (int i = 1; i < SpatialBinAmount; i++)
            {
                SpatialBin left  = new(clipPlaneCreator, binStart, binSize *i);
                SpatialBin right = new(clipPlaneCreator, binSize *i, binEnd);
                // Populate Split
                foreach (ISceneObject primitive in Items)
                {
                    int binID1 = (int)(k1 * (axis(primitive.Shape.BoundingBox.MinCorner.Vector) - axis(Shape.BoundingBox.MinCorner.Vector)));
                    int binID2 = (int)(k1 * (axis(primitive.Shape.BoundingBox.MaxCorner.Vector) - axis(Shape.BoundingBox.MinCorner.Vector)));
                    if (binID1 < i && binID2 < i)
                    {
                        left.Aggregate.Add(primitive);
                    }
                    else if (binID1 > i && binID2 > i)
                    {
                        right.Aggregate.Add(primitive);
                    }
                    else
                    {
                        left.ClipAndAdd(primitive);
                        right.ClipAndAdd(primitive);
                    }
                }
                // Evaluate Split
                Split split     = new(splitDirection, left.Aggregate, right.Aggregate);
                float splitCost = split.SurfaceAreaHeuristic;
                if (splitCost < bestSplitCost)
                {
                    bestSplitCost = splitCost;
                    bestSplit     = split;
                }
            }
            // TODO: Reference Unsplitting on best Split
            return(bestSplit);
        }
Ejemplo n.º 15
0
        public SurfaceInteraction(Point3 <float> p, Vector3 <float> pError, Point2 <float> uv, Vector3 <float> wo,
                                  Vector3 <float> dpdu, Vector3 <float> dpdv, Normal3 <float> dndu, Normal3 <float> dndv,
                                  float time, Shape shape)
            : base(p, new Normal3 <float>(Vector3 <float> .Cross(dpdu, dpdv).Normalized()), pError, wo, time)
        {
            Uv    = uv;
            DpDu  = dpdu;
            DpDv  = dpdv;
            DnDu  = dndu;
            DnDv  = dndv;
            Shape = shape;

            // Initialize the shading data from the true geometry
            Shading.N    = N;
            Shading.DpDu = DpDu;
            Shading.DpDv = DpDv;
            Shading.DnDu = DnDu;
            Shading.DnDv = DnDv;
        }
Ejemplo n.º 16
0
        Vector3 SampleVNDF(float r1, float r2)
        {
            // Rotate so UnitZ is up, and flip incoming to outgoing direction
            Normal3 up = Normal3.UnitZ;

            OpenTK.Mathematics.Quaternion rotation;
            if (Orientation == -up)
            {
                rotation = new OpenTK.Mathematics.Quaternion(Normal3.AnyPerpendicular(up).Vector, 0f);
            }
            else
            {
                rotation = new OpenTK.Mathematics.Quaternion(Vector3.Cross(Orientation.Vector, up.Vector), Vector3.Dot(Orientation.Vector, up.Vector) + 1f).Normalized();
            }
            Vector3 Ve = rotation * -IncomingDirection.Vector;

            // Section 3.2: transforming the view direction to the hemisphere configuration
            Vector3 Vh = new Vector3(Roughness * Ve.X, Roughness * Ve.Y, Ve.Z).Normalized();

            // Section 4.1: orthonormal basis (with special case if cross product is zero)
            float   lensq = Vh.X * Vh.X + Vh.Y * Vh.Y;
            Vector3 T1    = lensq > 0 ? new Vector3(-Vh.Y, Vh.X, 0) / (float)Math.Sqrt(lensq) : new Vector3(1f, 0f, 0f);
            Vector3 T2    = Vector3.Cross(Vh, T1);

            // Section 4.2: parameterization of the projected area
            float r   = (float)Math.Sqrt(r1);
            float phi = 2.0f * (float)Math.PI * r2;
            float t1  = r * (float)Math.Cos(phi);
            float t2  = r * (float)Math.Sin(phi);
            float s   = 0.5f * (1f + Vh.Z);

            t2 = (1f - s) * (float)Math.Sqrt(1f - t1 * t1) + s * t2;

            // Section 4.3: reprojection onto hemisphere
            Vector3 Nh = t1 * T1 + t2 * T2 + (float)Math.Sqrt(Math.Max(0f, 1f - t1 * t1 - t2 * t2)) * Vh;

            // Section 3.4: transforming the normal back to the ellipsoid configuration
            Vector3 Ne = new(Roughness * Nh.X, Roughness *Nh.Y, (float)Math.Max(0.0, Nh.Z));

            return(rotation.Inverted() * Ne);
        }
Ejemplo n.º 17
0
        public bool TryIntersect(
            Ray ray,
            double tmin,
            double tmax,
            ref ShadeRecord sr)
        {
            var origin = new Point3(
                this.cosTheta * ray.Origin.X - this.sinTheta * ray.Origin.Z,
                ray.Origin.Y,
                this.sinTheta * ray.Origin.X + this.cosTheta * ray.Origin.Z);

            var direction = new Vector3(
                this.cosTheta * ray.Direction.X - this.sinTheta * ray.Direction.Z,
                ray.Direction.Y,
                this.sinTheta * ray.Direction.X + this.cosTheta * ray.Direction.Z);

            var rotatedRay = new Ray(origin, direction, ray.Time);

            if (!this.obj.TryIntersect(rotatedRay, tmin, tmax, ref sr))
            {
                return(false);
            }

            var p = new Point3(
                this.cosTheta * sr.Point.X + this.sinTheta * sr.Point.Z,
                sr.Point.Y,
                -this.sinTheta * sr.Point.X + this.cosTheta * sr.Point.Z);

            var n = new Normal3(
                this.cosTheta * sr.Normal.X + this.sinTheta * sr.Normal.Z,
                sr.Normal.Y,
                -this.sinTheta * sr.Normal.X + this.cosTheta * sr.Normal.Z);

            sr.Point = p;
            sr.SetFaceNormal(rotatedRay, n);

            return(true);
        }
Ejemplo n.º 18
0
 public bool Contains(Normal3 sample) => IDirection3.InSameClosedHemisphere(Orientation, sample);
Ejemplo n.º 19
0
 public HemisphericalUniform(Normal3 orientation)
 {
     Orientation = orientation;
 }
Ejemplo n.º 20
0
 public void SetShadingGeometry(Vector3 <float> dpdu, Vector3 <float> dpdv, Normal3 <float> dndu, Normal3 <float> dndv)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 21
0
 public ISpectrum GetEmittance(Position3 position, Normal3 orientation, Normal3 direction)
 {
     return(Spectrum);
 }
Ejemplo n.º 22
0
 public IProbabilityDistribution <Normal3> GetDirections(Normal3 incomingDirection, Position3 position, Normal3 orientation, ISpectrum spectrum)
 {
     return(new SphericalUniform());
 }
Ejemplo n.º 23
0
 /// <summary> Create a new split with AABB's </summary>
 /// <param name="left">The left AABB</param>
 /// <param name="right">The right AABB</param>
 public Split(Normal3 direction, IAggregate left, IAggregate right)
 {
     Direction = direction;
     Left      = left;
     Right     = right;
 }
Ejemplo n.º 24
0
 public IProbabilityDistribution <Normal3> GetDirections(Normal3 incomingDirection, Position3 position, Normal3 orientation, ISpectrum spectrum)
 {
     throw new NotImplementedException("Requires structure to remember indices of refraction");
 }
Ejemplo n.º 25
0
 /// <summary> Create a new split with primitives </summary>
 /// <param name="primitivesLeft">The primitives for the left AABB</param>
 /// <param name="primitivesRight">The primitives for the right AABB</param>
 public Split(Normal3 direction, IEnumerable <ISceneObject> primitivesLeft, IEnumerable <ISceneObject> primitivesRight)
 {
     Direction = direction;
     Left      = new Aggregate(primitivesLeft);
     Right     = new Aggregate(primitivesRight);
 }
Ejemplo n.º 26
0
 public double ProbabilityDensity(Normal3 sample) => Contains(sample) ? 1 / DomainSize : 0;
Ejemplo n.º 27
0
 public IRay GetRay(Position3 position, Normal3 orientation, Normal3 direction)
 {
     return(new Ray(position, direction));
 }
Ejemplo n.º 28
0
 public IProbabilityDistribution <Normal3> GetOrientations(Position3 position, Normal3 direction, IShape shape)
 {
     return(new UniformPMF <Normal3>(shape.OutwardsDirection(position)));
 }
Ejemplo n.º 29
0
 public ISpectrum GetAlbedo(Position3 position, Normal3 orientation, Normal3 direction)
 {
     return(Albedo);
 }
Ejemplo n.º 30
0
 public IProbabilityDistribution <Normal3> GetDirections(Normal3 incomingDirection, Position3 position, Normal3 orientation, ISpectrum spectrum)
 {
     return(new HemisphericalDiffuse(orientation));
 }