Ejemplo n.º 1
0
 public DiskLight(Transformation objectToWorld, float radius = 1, SampledSpectrum spectrum = null)
     : base(objectToWorld, spectrum)
 {
     _radius  = radius;
     _normal  = ObjectToWorld.TransformNormal(new Vector3(0, -1, 0)).Normalized();
     NSamples = (uint)Math.Max(1, _radius / 4f);
 }
Ejemplo n.º 2
0
        public override Ray GenerateRay(Sample sample)
        {
            var ray = new Ray(new Vector3(_screenLeft + sample.X, _screenUp - sample.Y, FocalDistance).Normalized(),
                              Vector3.Zero);

            return(ObjectToWorld.TransformRay(ray));
        }
        public void OnCreate(ECSWorld world)
        {
            var fragShader = Asset.Load <ShaderAsset>("mesh_instanced_default.frag");
            var vertShader = Asset.Load <ShaderAsset>("mesh_instanced_default.vert");
            var shader     = new ShaderPipeline(fragShader, vertShader, ShaderType.Instanced);

            defaultShader = shader.ShaderPair;

            defaultMaterial = new Material(GraphicsContext.graphicsDevice,
                                           GraphicsContext.uniform0, defaultShader);
            defaultMaterial.wireframe = true;

            instanceMatrix = new DeviceBuffer(GraphicsContext.graphicsDevice, (ulong)Unsafe.SizeOf <ObjectToWorld>(),
                                              BufferUsageFlags.VertexBuffer, BufferMemoryUsageHint.Dynamic);


            var matrix       = mat4.Identity;
            var normalMatrix = new mat3(matrix);

            ObjectToWorld matrices = new ObjectToWorld()
            {
                model  = matrix,
                normal = normalMatrix
            };

            instanceMatrix.SetData(matrices, 0);

            MeshData initialData = new MeshData();

            initialData.subMeshes    = new SubMeshData[1];
            initialData.subMeshes[0] = new SubMeshData(vertices, indices);

            defaultMesh = new Mesh(GraphicsContext.graphicsDevice, initialData, true);
        }
Ejemplo n.º 4
0
        public override (SurfaceInteraction, double) Sample()
        {
            // TODO: Implement Sphere sampling
            if (Outside)
            {
                var pObj = this.Radius * Samplers.UniformSampleSphere();
                var n    = new Vector3(pObj.x, pObj.y, pObj.z);
                var pdf  = 1 / this.Area();
                var dpdu = new Vector3(-pObj.y, pObj.x, 0);

                SurfaceInteraction si = new SurfaceInteraction(pObj, n, Vector3.ZeroVector, dpdu, this);
                return(ObjectToWorld.Apply(si), pdf);
            }
            else
            {
                var pObj = this.Radius * Samplers.UniformSampleSphere();
                var n    = new Vector3(pObj.x, pObj.y, pObj.z);
                var pdf  = 1 / this.Area();
                var dpdu = new Vector3(-pObj.y, pObj.x, 0);

                SurfaceInteraction si = new SurfaceInteraction(pObj, -n, Vector3.ZeroVector, dpdu, this);
                return(ObjectToWorld.Apply(si), pdf);
            }

            // TODO: Return surface interaction and pdf

            // A dummy return example
            //double dummyPdf = 1.0;
            //Vector3 dummyVector = new Vector3(0, 0, 0);
            //SurfaceInteraction dummySurfaceInteraction = new SurfaceInteraction(dummyVector, dummyVector, dummyVector, dummyVector, this);
            //return (dummySurfaceInteraction, dummyPdf);
        }
Ejemplo n.º 5
0
 public override Point Sample(float u1, float u2, out Normal ns)
 {
     var z = MathUtility.Lerp(u1, _zMin, _zMax);
     var t = u2 * _phiMax;
     var p = new Point(_radius * MathUtility.Cos(t), _radius * MathUtility.Sin(t), z);
     ns = Normal.Normalize(ObjectToWorld.TransformNormal(new Normal(p.X, p.Y, 0)));
     if (ReverseOrientation)
         ns *= -1.0f;
     return ObjectToWorld.TransformPoint(ref p);
 }
Ejemplo n.º 6
0
        public override Point Sample(float u1, float u2, out Normal ns)
        {
            Point p = new Point(0, 0, 0) + _radius * MonteCarloUtilities.UniformSampleSphere(u1, u2);

            ns = Normal.Normalize(ObjectToWorld.TransformNormal(new Normal(p.X, p.Y, p.Z)));
            if (ReverseOrientation)
            {
                ns *= -1.0f;
            }
            return(ObjectToWorld.TransformPoint(ref p));
        }
Ejemplo n.º 7
0
        public override (SurfaceInteraction, double) Sample()
        {
            var pObj = Samplers.UniformSampleSphere() * Radius;

            pObj *= Radius / pObj.Length(); // refine
            var n    = pObj.Normalize();
            var dpdu = new Vector3(-pObj.y, pObj.x, 0);
            var pdf  = 1 / Area();

            return(ObjectToWorld.Apply(new SurfaceInteraction(pObj, n, Vector3.ZeroVector, dpdu, this)), pdf);
        }
Ejemplo n.º 8
0
        public override (SurfaceInteraction, double) Sample()
        {
            (double x, double y) = Samplers.UniformSampleDisk();

            var pObj = new Vector3(x * radius, y * radius, height);

            var    n    = new Vector3(0, 0, 1);
            var    dpdu = new Vector3(-pObj.y, pObj.x, 0);
            double pdf  = 1 / Area();

            return(ObjectToWorld.Apply(new SurfaceInteraction(pObj, n, Vector3.ZeroVector, dpdu, this)), pdf);
        }
Ejemplo n.º 9
0
        public override (SurfaceInteraction, double) Sample()
        {
            (double x, double y) = Samplers.UniformSampleSquare();

            var pObj = new Vector3((x - 0.5) * width, (y - 0.5) * height, 0);

            var    n    = new Vector3(0, 0, 1);
            var    dpdu = new Vector3(1, 0, 0);
            double pdf  = 1 / Area();

            return(ObjectToWorld.Apply(new SurfaceInteraction(pObj, n, Vector3.ZeroVector, dpdu, this)), pdf);
        }
Ejemplo n.º 10
0
        public override (SurfaceInteraction, double) Sample()
        {
            Vector3 sample = Samplers.UniformSampleSphere();
            Vector3 point  = sample * Radius;
            Vector3 normal = sample;
            Vector3 dpdu   = new Vector3(-normal.y, normal.x, 0.0);
            double  pdf    = 1.0 / Area();

            SurfaceInteraction si = new SurfaceInteraction(point, normal, Vector3.ZeroVector, dpdu, this);

            return(ObjectToWorld.Apply(si), pdf);
        }
Ejemplo n.º 11
0
        public override (SurfaceInteraction, double) Sample()
        {
            // TODO: Implement Sphere sampling
            //Vector3 pObj = Samplers.CosineSampleHemisphere() * Radius;
            Vector3 pObj = Samplers.UniformSampleSphere() * Radius;

            pObj = pObj * (Radius / pObj.Length());

            // TODO: Return surface interaction and pdf
            var    dpdu = new Vector3(-pObj.y, pObj.x, 0);
            double pdf  = 1 / Area(); // a je kle inv 4 PI (1/Math.PI/4)

            return(ObjectToWorld.Apply(new SurfaceInteraction(pObj, ObjectToWorld.ApplyNormal(pObj), Vector3.ZeroVector, dpdu, this)), pdf);
        }
Ejemplo n.º 12
0
        public override SampledSpectrum Sample(ref Vector3 point, Scene scene, out Vector3 incomingVector,
                                               out VisibilityTester visibilityTester)
        {
            var r1 = StaticRandom.NextFloat() * 2 - 1;
            var r2 = StaticRandom.NextFloat() * 2 - 1;
            var pointInDiskLocal = new Vector3(r1 * _radius, 0, r2 * _radius);
            var pointInDiskWorld = ObjectToWorld.TransformPoint(ref pointInDiskLocal);

            incomingVector = point - pointInDiskWorld;
            var cosangle = Vector3.Dot(incomingVector.Normalized(), _normal);

            visibilityTester = new VisibilityTester(pointInDiskWorld, point, scene);
            return(Spectrum * cosangle / incomingVector.Length);
        }
Ejemplo n.º 13
0
        public override Point Sample(float u1, float u2, out Normal ns)
        {
            var p = new Point();

            MonteCarloUtilities.ConcentricSampleDisk(u1, u2, out p.X, out p.Y);
            p.X *= _radius;
            p.Y *= _radius;
            p.Z  = _height;
            ns   = Normal.Normalize(ObjectToWorld.TransformNormal(new Normal(0, 0, 1)));
            if (ReverseOrientation)
            {
                ns *= -1.0f;
            }
            return(ObjectToWorld.TransformPoint(ref p));
        }
Ejemplo n.º 14
0
        public override float Pdf(Point p, Vector wi)
        {
            Point Pcenter = ObjectToWorld.TransformPoint(Point.Zero);

            // Return uniform weight if point inside sphere
            if (Point.DistanceSquared(p, Pcenter) - _radius * _radius < 1e-4f)
            {
                return(base.Pdf(p, wi));
            }

            // Compute general sphere weight
            float sinThetaMax2 = _radius * _radius / Point.DistanceSquared(p, Pcenter);
            float cosThetaMax  = MathUtility.Sqrt(Math.Max(0.0f, 1.0f - sinThetaMax2));

            return(MonteCarloUtilities.UniformConePdf(cosThetaMax));
        }
Ejemplo n.º 15
0
        public override (SurfaceInteraction, double) Sample(SurfaceInteraction _si)
        {
            SurfaceInteraction si  = WorldToObject.Apply(_si);
            double             dc2 = si.Point.LengthSquared();

            if (dc2 <= Radius * Radius)
            {
                // Point inside sphere
                return(base.Sample(_si));
            }

            // Point outside sphere
            double dc = Math.Sqrt(dc2);

            double sinThetaMax = Radius / dc;
            double cosThetaMax = Utils.SinToCos(sinThetaMax);

            // Determine theta and phi for uniform cone sampling
            double cosTheta = (cosThetaMax - 1) * Samplers.ThreadSafeRandom.NextDouble() + 1;
            double sinTheta = Utils.CosToSin(cosTheta);
            double phi      = Samplers.ThreadSafeRandom.NextDouble() * 2.0 * Math.PI;

            // Distance between reference point and sample point on sphere
            double ds = dc * cosTheta - Math.Sqrt(Math.Max(0, Radius * Radius - dc2 * sinTheta * sinTheta));

            // Kosinusni zakon
            double cosAlpha = (dc2 + Radius * Radius - ds * ds) / (2 * dc * Radius);
            double sinAlpha = Utils.CosToSin(cosAlpha);

            // Construct coordinate system and use phi and theta as spherical coordinates to get point on sphere
            Vector3 wcZ = si.Point.Clone().Normalize();

            (Vector3 wcX, Vector3 wcY) = Utils.CoordinateSystem(wcZ);

            Vector3 nObj = Utils.SphericalDirection(sinAlpha, cosAlpha, phi, wcX, wcY, wcZ);
            Vector3 pObj = nObj * Radius;

            // Surface interaction
            Vector3            dpdu     = new Vector3(-nObj.y, nObj.x, 0.0);
            SurfaceInteraction siSample = new SurfaceInteraction(pObj, nObj, Vector3.ZeroVector, dpdu, this);

            // Uniform cone PDF
            double pdf = Samplers.UniformConePdf(cosThetaMax);

            return(ObjectToWorld.Apply(siSample), pdf);
        }
Ejemplo n.º 16
0
        public override (SurfaceInteraction, double) Sample()
        {
            // TODO: Implement Sphere sampling
            var center = new Vector3(0, 0, 0);
            var point  = center + Radius * Samplers.UniformSampleSphere();

            var normal = point.Normalize();

            if (innerOrientation)
            {
                normal = -normal;
            }

            point *= Radius / (center - point).Length();
            var wo          = point;
            var dpdu        = Dpdu(point);
            var interaction = new SurfaceInteraction(point, normal, wo, dpdu, this);

            return(ObjectToWorld.Apply(interaction), Pdf(interaction, point));
        }
Ejemplo n.º 17
0
        public override Point Sample(Point p, float u1, float u2, out Normal ns)
        {
            // Compute coordinate system for sphere sampling
            Point  Pcenter = ObjectToWorld.TransformPoint(Point.Zero);
            Vector wc = Vector.Normalize(Pcenter - p);
            Vector wcX, wcY;

            Vector.CoordinateSystem(wc, out wcX, out wcY);

            // Sample uniformly on sphere if $\pt{}$ is inside it
            if (Point.DistanceSquared(p, Pcenter) - _radius * _radius < 1e-4f)
            {
                return(Sample(u1, u2, out ns));
            }

            // Sample sphere uniformly inside subtended cone
            float sinThetaMax2 = _radius * _radius / Point.DistanceSquared(p, Pcenter);
            float cosThetaMax  = MathUtility.Sqrt(Math.Max(0.0f, 1.0f - sinThetaMax2));
            DifferentialGeometry dgSphere;
            float thit, rayEpsilon;
            Point ps;
            Ray   r = new Ray(p, MonteCarloUtilities.UniformSampleCone(u1, u2, cosThetaMax, ref wcX, ref wcY, ref wc),
                              1e-3f);

            if (!TryIntersect(r, out thit, out rayEpsilon, out dgSphere))
            {
                thit = Vector.Dot(Pcenter - p, Vector.Normalize(r.Direction));
            }
            ps = r.Evaluate(thit);
            ns = (Normal)Vector.Normalize(ps - Pcenter);
            if (ReverseOrientation)
            {
                ns *= -1.0f;
            }
            return(ps);
        }
Ejemplo n.º 18
0
        public override (double?, SurfaceInteraction) Intersect(Ray ray)
        {
            Ray r = WorldToObject.Apply(ray);

            // TODO: Compute quadratic sphere coefficients

            // TODO: Initialize _double_ ray coordinate values
            (double dx, double dy, double dz) = (r.d.x, r.d.y, r.d.z);
            (double ox, double oy, double oz) = (r.o.x, r.o.y, r.o.z);
            double a = dx * dx + dy * dy + dz * dz;
            double b = 2 * (dx * ox + dy * oy + dz * oz);
            double c = ox * ox + oy * oy + oz * oz - this.Radius * this.Radius;

            // TODO: Solve quadratic equation for _t_ values
            (bool zzz, double t0, double t1) = Utils.Quadratic(a, b, c);
            if (!zzz)
            {
                return(null, null);
            }

            // TODO: Check quadric shape _t0_ and _t1_ for nearest intersection
            //double tShapeHit;
            //if (t1 < Renderer.Epsilon)
            //    return (null, null);
            //if (t0 < Renderer.Epsilon)
            //    tShapeHit = t1;
            //else
            //{
            //    Ray temp = new Ray(r.o, r.d);
            //    double d1 = Vector3.Dot(temp.Point(t0), temp.o);
            //    double d2 = Vector3.Dot(temp.Point(t1), temp.o);
            //    if (d1 == d2)
            //        return (null, null);
            //    else if (d1 > d2)
            //    {
            //        if (Outside)
            //            tShapeHit = t0;
            //        else
            //            tShapeHit = t1;
            //    }
            //    else
            //    {
            //        if (Outside)
            //            tShapeHit = t1;
            //        else
            //            tShapeHit = t0;
            //    }
            //}

            //if (t1 - t0 <= Renderer.Epsilon)
            //    return (null, null);

            //Ray temp = new Ray(r.o, r.d);
            //double d0 = Vector3.Dot(temp.o, temp.Point(t0));
            //double d1 = Vector3.Dot(temp.o, temp.Point(t1));
            //double tShapeHit;

            //if (d0 >= d1)
            //    tShapeHit = t0;
            //else
            //    tShapeHit = t1;

            if (Outside)
            {
                Console.WriteLine("HERE");

                //if (t1 < Renderer.Epsilon)
                //    return (null, null);
                //double tShapeHit = t0;
                //if (tShapeHit < Renderer.Epsilon)
                //{
                //    tShapeHit = t1;
                //}

                double  tShapeHit;
                Ray     temp = new Ray(r.o, r.d);
                Vector3 p_t0 = temp.Point(t0);
                Vector3 p_t1 = temp.Point(t1);
                double  d0   = Math.Sqrt(Math.Pow(temp.o.x - p_t0.x, 2) + Math.Pow(temp.o.y - p_t0.y, 2) + Math.Pow(temp.o.z - p_t0.z, 2));
                double  d1   = Math.Sqrt(Math.Pow(temp.o.x - p_t1.x, 2) + Math.Pow(temp.o.y - p_t1.y, 2) + Math.Pow(temp.o.z - p_t1.z, 2));

                if (d0 > d1)
                {
                    tShapeHit = t1;
                }
                else
                {
                    tShapeHit = t0;
                }

                //// TODO: Compute sphere hit position and $\phi$
                Vector3 pHit = r.Point(tShapeHit);
                //pHit *= Radius / Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y + pHit.z * pHit.z);

                //if (Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y + pHit.z * pHit.z) >= this.Radius + Renderer.Epsilon)
                //    return (null, null);
                //if (Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y + pHit.z * pHit.z) <= this.Radius - Renderer.Epsilon)
                //    return (null, null);

                //double phi = Math.Atan2(pHit.y, pHit.x);
                //if (phi < 0)
                //    phi += 2 * Math.PI;
                //double theta = Math.Acos(Utils.Clamp(pHit.z / this.Radius, -1, 1));

                //double invR = 1 / Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y);
                //Vector3 n = new Vector3(pHit.z * pHit.x * invR, pHit.z * pHit.y * invR, -this.Radius * Math.Sin(theta));

                Vector3 n = (ObjectToWorld.ApplyPoint(pHit) - ObjectToWorld.ApplyPoint(Vector3.ZeroVector)).Clone().Normalize();
                //Vector3 n = new Vector3(0, 0, 1);
                //Vector3 n = pHit.Clone() * this.Radius;

                // TODO: Return shape hit and surface interaction
                Vector3 dpdu = new Vector3(-pHit.y, pHit.x, 0);

                //Console.WriteLine("dpdu1 " + dpdu.x + " " + dpdu.y + " " + dpdu.z);

                n.Faceforward(dpdu);

                //Console.WriteLine("normal " + n.x + " " + n.y + " " + n.z);

                double abDot = Vector3.Dot(n, dpdu);
                double bbDot = Vector3.Dot(n, n);

                Vector3 proj = abDot / bbDot * n;

                dpdu -= proj;

                //Console.WriteLine("proj " + proj.x + " " + proj.y + " " + proj.z);

                //Console.WriteLine("dot " + Vector3.Dot(n, dpdu));

                var si = new SurfaceInteraction(pHit, n, -ray.d, dpdu, this);
                //var si = new SurfaceInteraction(pHit, new Vector3(0, 0, 1), -ray.d, dpdu, this);


                return(tShapeHit, ObjectToWorld.Apply(si));
            }
            else
            {
                //Console.WriteLine(r.o.x + " " + r.o.y + " " + r.o.z);
                //Console.WriteLine(t0);
                //Console.WriteLine(t1);
                //System.Environment.Exit(1);

                double  tShapeHit;
                Ray     temp = new Ray(r.o, r.d);
                Vector3 p_t0 = temp.Point(t0);
                Vector3 p_t1 = temp.Point(t1);

                Vector3 x = p_t0 - temp.o;
                Vector3 y = p_t1 - temp.o;

                double x_x = Vector3.Dot(x, temp.d);
                double y_x = Vector3.Dot(y, temp.d);

                //Console.WriteLine(temp.d.x + " " + temp.d.y + " " + temp.d.z);
                //Console.WriteLine(x_x);
                //Console.WriteLine(y_x);
                //System.Environment.Exit(1);

                if (x_x > 0)
                {
                    tShapeHit = t0;
                }
                else if (y_x > 0)
                {
                    tShapeHit = t1;
                }
                else
                {
                    return(null, null);
                }

                //// TODO: Compute sphere hit position and $\phi$
                Vector3 pHit = r.Point(tShapeHit);
                //pHit *= Radius / Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y + pHit.z * pHit.z);

                //if (Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y + pHit.z * pHit.z) >= this.Radius + Renderer.Epsilon)
                //    return (null, null);
                //if (Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y + pHit.z * pHit.z) <= this.Radius - Renderer.Epsilon)
                //    return (null, null);

                //double phi = Math.Atan2(pHit.y, pHit.x);
                //if (phi < 0)
                //    phi += 2 * Math.PI;
                //double theta = Math.Acos(Utils.Clamp(pHit.z / this.Radius, -1, 1));

                //double invR = 1 / Math.Sqrt(pHit.x * pHit.x + pHit.y * pHit.y);
                //Vector3 n = new Vector3(pHit.z * pHit.x * invR, pHit.z * pHit.y * invR, -this.Radius * Math.Sin(theta));

                Vector3 n = (ObjectToWorld.ApplyPoint(Vector3.ZeroVector) - ObjectToWorld.ApplyPoint(pHit)).Clone().Normalize();
                //Vector3 n = new Vector3(0, 0, 1);
                //Vector3 n = pHit.Clone() * this.Radius;

                // TODO: Return shape hit and surface interaction
                Vector3 dpdu = new Vector3(-pHit.y, pHit.x, 0);

                //Console.WriteLine("dpdu1 " + dpdu.x + " " + dpdu.y + " " + dpdu.z);

                dpdu.Faceforward(n);

                //Console.WriteLine("normal " + n.x + " " + n.y + " " + n.z);

                double abDot = Vector3.Dot(n, dpdu);
                double bbDot = Vector3.Dot(n, n);

                Vector3 proj = abDot / bbDot * n;

                dpdu -= proj;

                //Console.WriteLine("proj " + proj.x + " " + proj.y + " " + proj.z);

                //Console.WriteLine("dot " + Vector3.Dot(n, dpdu));

                var si = new SurfaceInteraction(pHit, n, -ray.d, dpdu, this);
                //var si = new SurfaceInteraction(pHit, new Vector3(0, 0, 1), -ray.d, dpdu, this);


                return(tShapeHit, ObjectToWorld.Apply(si));
            }

            // A dummy return example
            //double dummyHit = 0.0;
            //Vector3 dummyVector = new Vector3(0, 0, 0);
            //SurfaceInteraction dummySurfaceInteraction = new SurfaceInteraction(dummyVector, dummyVector, dummyVector, dummyVector, this);
            //return (dummyHit, dummySurfaceInteraction);
        }
Ejemplo n.º 19
0
 public virtual Bounds3D WorldBound()
 {
     return(ObjectToWorld.AtBounds(ObjectBound()));
 }