Пример #1
0
 public DiffuseAreaLight(Shape s, Spectrum l, double intensity = 1, SideEnum sd = SideEnum.Front)
 {
     shape = s;
     Lemit = l * intensity;
     side  = sd;
 }
Пример #2
0
 public Spectrum AddTo(Spectrum v2)
 {
     c += v2.c;
     return(this);
 }
Пример #3
0
        public Spectrum Li(Ray r, Scene s)
        {
            Spectrum L = Spectrum.ZeroSpectrum;
            Spectrum B = Spectrum.Create(1);

            int nbounces = 0;

            while (nbounces < 20)
            {
                SurfaceInteraction isect = null;

                //Get the object the ray intersected with
                isect = s.Intersect(r).Item2;

                //If the ray hasn't hit anything return 0
                if (isect == null)
                {
                    break;
                }

                Vector3 wo = isect.Wo;//-r.d;
                //If the ray hit a light, take its emission
                if (isect.Obj is Light)
                {
                    if (nbounces == 0)
                    {
                        L = B * isect.Le(wo);
                    }
                    break;
                }

                //Create a light ray from the intersection point and add its emission
                Spectrum Ld = Light.UniformSampleOneLight(isect, s);
                L = L.AddTo(B * Ld);


                //Get the materials value at this point
                (Spectrum f, Vector3 wi, double pr, bool specular) = (isect.Obj as Shape).BSDF.Sample_f(wo, isect);

                if (!specular)
                {
                    B = B * f * Utils.AbsCosTheta(wi) / pr;
                }


                //Spawn a new ray from the intersection
                r = isect.SpawnRay(wi);

                if (nbounces > 3)
                {
                    double q = 1.0 - B.Max();
                    if (ThreadSafeRandom.NextDouble() < q)
                    {
                        break;
                    }
                    B = B / (1 - q);
                }
                nbounces++;
            }

            return(L);
        }
 public Lambertian(Spectrum r)
 {
     kd = r;
 }
Пример #5
0
 public OrenNayar(Spectrum r, double roughness)
 {
     kd       = r;
     this.cov = roughness * roughness;
 }
Пример #6
0
        public Spectrum Li(Ray ray, Scene s)
        {
            var  L              = Spectrum.ZeroSpectrum;
            var  beta           = Spectrum.Create(1.0);
            bool specularBounce = false;

            for (int nBounces = 0; nBounces < 20; nBounces++)
            {
                (double?d, SurfaceInteraction si) = s.Intersect(ray);

                Vector3 wo = -ray.d;

                if (nBounces == 0 || specularBounce)
                {
                    if (d != null)
                    {
                        L.AddTo(beta * si.Le(wo));
                    }
                    else
                    {
                        foreach (var light in s.Lights)
                        {
                            L.AddTo(beta * Spectrum.ZeroSpectrum); // light.Le()
                        }
                    }
                }


                if (d == null)
                {
                    break;
                }


                if (si.Obj is Light)
                {
                    //if (nBounces == 0)
                    //{
                    //    L.AddTo(beta * si.Le(wo));
                    //}
                    break;
                }

                if (!specularBounce)
                {
                    L.AddTo(beta * Light.UniformSampleOneLight(si, s));
                }

                (Spectrum f, Vector3 wiW, double pdf, bool bxdfIsSpecular) = ((Shape)si.Obj).BSDF.Sample_f(wo, si);

                specularBounce = bxdfIsSpecular;

                if (f.IsBlack() || pdf == 0)
                {
                    break;
                }

                var wi = si.SpawnRay(wiW);

                beta = beta * f * Vector3.AbsDot(wiW, si.Normal) / pdf;
                ray  = wi;

                if (nBounces > 3)
                {
                    double q = 1 - beta.Max();
                    if (ThreadSafeRandom.NextDouble() < q)
                    {
                        break;
                    }
                    beta = beta / (1 - q);
                }
            }

            return(L);
        }
Пример #7
0
 public SpecularTransmission(Spectrum r, double fresnel1, double fresnel2)
 {
     this.r  = r;
     fresnel = new FresnelDielectric(fresnel1, fresnel2);
 }
Пример #8
0
        /// <summary>
        /// Generate Cornell Box Geometry
        /// </summary>
        /// <returns></returns>
        public static Scene CornellBox()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -548),
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5.2
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            //right
            el = new Quad(559.2, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            //left
            el = new Quad(559.2, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Gray)));
            s.Elements.Add(el);

            double shade     = 1;
            double intensity = 20;

            s.Elements.Add(new DiffuseAreaLight(new Quad(556, 200, Transform.Translate(278, 548, 559.2 - 400).A(Transform.RotateX(90))), Spectrum.Create(1), intensity));
            s.Elements.Add(new DiffuseAreaLight(new Quad(556, 200, Transform.Translate(278, 0.1, 559.2 - 400).A(Transform.RotateX(270))), Spectrum.Create(1), intensity));
            //s.Elements.Add(new RectangleLight(new Quad(556, 200, Transform.Translate(278, 548.8 / 2, 559.2 - 200).A(Transform.RotateX(270))), Spectrum.Create(1), intensity, false));
            //s.Elements.Add(new RectangleLight(new Quad(100, 200, Transform.Translate(278, 548.8 * 3 / 4, 559.2 - 200).A(Transform.RotateX(270))), Spectrum.Create(1), intensity, false));
            //s.Elements.Add(new RectangleLight(new Quad(100, 200, Transform.Translate(278, 548.8 * 1 / 4, 559.2 - 200).A(Transform.RotateX(270))), Spectrum.Create(1), intensity, false));
            //left
            //s.Elements.Add(new DiffuseAreaLight(new Quad(548.8, 556.0, Transform.Translate(0.1, 548.8 / 2, 559.2).A(Transform.RotateY(90))), Spectrum.Create(shade), intensity));
            //right
            //s.Elements.Add(new DiffuseAreaLight(new Quad(548.8, 556.0, Transform.Translate(555.9, 548.8 / 2, 559.2).A(Transform.RotateY(270))), Spectrum.Create(shade), intensity));


            //s.Elements.Add(new DiffuseAreaLight(new Disk(80, 0.1, Transform.Translate(278, 0, 280).A(Transform.RotateX(-90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new RectangleLight(new Quad(160, 80, Transform.Translate(278, 278, 350).A(Transform.RotateX(135))), Spectrum.Create(1), 20));

            double gridSize   = 4;
            double sphereSize = 70;
            double offsetX    = 550 / gridSize;
            double offsetY    = 550 / gridSize;
            double row        = 0;
            double column     = 0;
            double z          = 400;

            string[] models =
            {
                "beige-fabric",         "yellow-matte-plastic", "green-plastic",      "neoprene-rubber",
                "blue-rubber",          "polyurethane-foam",    "special-walnut-224", "yellow-phenolic",
                "green-metallic-paint", "red-metallic-paint",   "violet-acrylic",     "grease-covered-steel",
                "aluminium",            "alum-bronze",          "two-layer-silver",   "two-layer-gold"
            };

            foreach (string model in models)
            {
                el = new Sphere(sphereSize, Transform.Translate((column + 0.5) * offsetX, (row + 0.5) * offsetY, z));

                column++;
                if (column % gridSize == 0)
                {
                    row++;
                    column = 0;
                }
                el.BSDF.Add(new MERL(model, true));
                //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1, 1.5));
                s.Elements.Add(el);
            }



            return(s);
        }
Пример #9
0
        /// <summary>
        /// Generate Cornell Box Geometry
        /// </summary>
        /// <returns></returns>
        public static Scene CornellBox()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -548), // -800
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 7                              // 5.5
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2 * 3, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2 * 3, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back2
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, -550).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);


            //double[] brdfs2 = ReadMerl.Read(@"D:\NRG seminarska\green-plastic.binary");
            //right
            el = new Quad(559.2 * 3, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Green)));
            //el.BSDF.Add(new Merl(brdfs2));
            s.Elements.Add(el);

            //left
            el = new Quad(559.2 * 3, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Red)));
            s.Elements.Add(el);

            // luč
            // kvadratna luč
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, 220).A(Transform.RotateX(90))), Spectrum.Create(1), 25));
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, -280).A(Transform.RotateX(90))), Spectrum.Create(1), 25));

            //s.Elements.Add(new DiffuseAreaLight(new Disk(100, 0.1, Transform.Translate(278, 548, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Disk(100, 0.1, Transform.Translate(278, 548, 0).A(Transform.RotateX(90))), Spectrum.Create(1), 30));
            //s.Elements.Add(new DiffuseAreaLight(new Disk(100, 0.1, Transform.Translate(278, 548, -280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(80, Transform.Translate(278, 548, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(80, Transform.Translate(278, 548, 280)), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(60, Transform.Translate(278, 280, 300).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(80, Transform.Translate(400, 80, 400).A(Transform.RotateX(90))), Spectrum.Create(1), 20));
            //s.Elements.Add(new DiffuseAreaLight(new Sphere(1100, Transform.Translate(278, 280, 280).A(Transform.RotateX(90))), Spectrum.Create(1), 20));

            double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\gold-metallic-paint.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-acrylic.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-diffuse-bball.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-fabric.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-fabric2.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-marble.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\white-paint.binary");
            //double[] brdfs0 = ReadMerl.Read(@"D:\NRG seminarska\ss440.binary");

            // modra krogla
            //el = new Sphere(100, Transform.Translate(150, 100, 420));
            //el = new Sphere(130, Transform.Translate(180, 130, 400));
            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 0, 0));
            //el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Blue)));
            //el.BSDF.Add(new OrenNayar(Spectrum.ZeroSpectrum.FromRGB(Color.Blue), 10));
            //el.BSDF.Add(new Merl(brdfs1));
            //s.Elements.Add(el);

            //rumena krogla
            //el = new Sphere(130, Transform.Translate(400, 130, 230));
            el = new Sphere(200, Transform.Translate(250, 200, 230));

            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White),0,0));
            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White),0.25,0.6));
            //el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            //el.BSDF.Add(new OrenNayar(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow), 5));
            el.BSDF.Add(new Merl(brdfs0));
            //el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1, 1.5));
            s.Elements.Add(el);


            //el = new Sphere(60, Transform.Translate(180, 60, 100));
            //el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Yellow)));
            //s.Elements.Add(el);

            return(s);
        }
Пример #10
0
        public static Scene AllMerlInOne()
        {
            var s = new Scene()
            {
                CameraOrigin    = new Vector3(278, 274.4, -548), // -800
                AspectRatio     = 1.0 / 1.0,
                ImagePlaneWidth = 5                              // 5.5
            };

            Shape el;

            // floor
            el = new Quad(556.0, 559.2 * 2, Transform.Translate(556.0 / 2, 0, 559.2 / 2).A(Transform.RotateX(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // celing
            el = new Quad(556.0, 559.2 * 2, Transform.Translate(556.0 / 2, 548.8, 559.2 / 2).A(Transform.RotateX(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, 559.2).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // back2
            el = new Quad(556.0, 548.8, Transform.Translate(556.0 / 2, 548.8 / 2, -550).A(Transform.RotateX(180)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.White)));
            s.Elements.Add(el);

            // right
            el = new Quad(559.2 * 2, 548.8, Transform.Translate(556.0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Green)));
            s.Elements.Add(el);

            // left
            el = new Quad(559.2 * 2, 548.8, Transform.Translate(0, 548.8 / 2, 559.2 / 2).A(Transform.RotateY(-90)));
            el.BSDF.Add(new Lambertian(Spectrum.ZeroSpectrum.FromRGB(Color.Red)));
            s.Elements.Add(el);

            // luč
            // kvadratna luč
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, 200).A(Transform.RotateX(90))), Spectrum.Create(1), 31));
            s.Elements.Add(new DiffuseAreaLight(new Quad(170, 170, Transform.Translate(278, 548, -280).A(Transform.RotateX(90))), Spectrum.Create(1), 35));



            DirectoryInfo d = new DirectoryInfo(@"D:\NRG seminarska\");

            FileInfo[] Files = d.GetFiles("*.binary");


            //int xOff = 25;
            //int yOff = 25;
            //int countSpheres = 0;
            //foreach (FileInfo file in Files)
            //{
            //    double[] brdf0 = ReadMerl.Read(@"D:\NRG seminarska\" + file.Name);

            //    el = new Sphere(25, Transform.Translate(xOff, yOff, 400));
            //    el.BSDF.Add(new Merl(brdf0));
            //    s.Elements.Add(el);

            //    countSpheres++;
            //    xOff += 52;
            //    if (countSpheres % 10 == 0)
            //    {
            //        yOff += 52;
            //        xOff = 25;
            //    }

            //    if (countSpheres == 49)
            //    {
            //        //break;
            //    }
            //}


            //int xOff = 38;
            //int yOff = 38;
            //int countSpheres = 0;
            //foreach (FileInfo file in Files)
            //{
            //    //if (countSpheres < 49) {
            //    //    countSpheres++;
            //    //    continue;
            //    //}

            //    double[] brdf0 = ReadMerl.Read(@"D:\NRG seminarska\" + file.Name);

            //    el = new Sphere(36, Transform.Translate(xOff, yOff, 480));
            //    el.BSDF.Add(new Merl(brdf0));
            //    s.Elements.Add(el);

            //    countSpheres++;
            //    xOff += 77;
            //    if (countSpheres % 7 == 0)
            //    {
            //        yOff += 77;
            //        xOff = 38;
            //    }

            //    if (countSpheres == 49) //49 //98
            //    {
            //        break;
            //    }
            //}


            int xOff         = 55;
            int yOff         = 55;
            int countSpheres = 0;

            foreach (FileInfo file in Files)
            {
                double[] brdf0 = ReadMerl.Read(@"D:\NRG seminarska\" + file.Name);

                el = new Sphere(50, Transform.Translate(xOff, yOff, 480));
                el.BSDF.Add(new Merl(brdf0));
                el.BSDF.Add(new SpecularReflection(Spectrum.ZeroSpectrum.FromRGB(Color.White), 1, 1.5));
                s.Elements.Add(el);

                countSpheres++;
                xOff += 105;
                if (countSpheres % 5 == 0)
                {
                    yOff += 105;
                    xOff  = 55;
                }

                if (countSpheres == 25)
                {
                    break;
                }
            }



            return(s);
        }
Пример #11
0
        public void Render(Scene s, CancellationToken token)
        {
            var integrator = new PathTracer();

            // Use ParallelOptions instance to store the CancellationToken
            ParallelOptions po = new ParallelOptions()
            {
                MaxDegreeOfParallelism = 8,
                CancellationToken      = token
            };

            try
            {
                //DirectoryInfo d = new DirectoryInfo(@"D:\NRG seminarska\");
                //FileInfo[] Files = d.GetFiles("*.binary");

                //foreach (FileInfo file in Files)
                //{
                //Scene.brdfFileName = file.Name;
                //Console.WriteLine(file.Name);
                //while (totalSamples < maxTotalSamples)
                while (true)
                {
                    var samples = SamplePointsOnImagePlane(s, 1);
                    Parallel.ForEach(samples, po, samp =>
                    {
                        // if cancel requested from GUI, cancel
                        token.ThrowIfCancellationRequested();

                        var rayTo = new Vector3(samp.X - s.ImagePlaneWidth / 2, samp.Y - s.ImagePlaneHeight / 2 + s.ImagePlaneVerticalOffset, s.ImagePlaneDistance);
                        // ray through point
                        Ray r = new Ray(s.CameraOrigin, rayTo);

                        // evaluate radiance
                        Spectrum L = integrator.Li(r, s);

                        // add radiance to image
                        AddToImage(samp, L, s);
                    });
                }

                //Neki:
                //    try
                //    {
                //        finalRgbImage.Save(@"D:\NRG seminarska\" + DateTime.Now.ToString().Replace("/", "-").Replace(":", "-").Replace(" ", "_") + "_" + file.Name.Replace(".binary", "") + ".png", ImageFormat.Png);
                //    }
                //    catch (Exception)
                //    {
                //        Thread.Sleep(1);
                //        goto Neki;
                //    }
                //    s = Scene.CornellBox();
                //    finalImageSum = new Spectrum[pixelWidth, pixelHeight];
                //    finalImage = new Spectrum[pixelWidth, pixelHeight];
                //    finalRgbImage = new Bitmap(160, (int)Math.Round(160 / s.AspectRatio), PixelFormat.Format24bppRgb);
                //    pixelWeights = new double[pixelWidth, pixelHeight];
                //    bmp = finalRgbImage;
                //    totalSamples = 0;
                //bmp = b;
                //}
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception e) {
                Console.WriteLine(e);
            }
        }
Пример #12
0
 public RectangleLight(Quad q, Spectrum l, double intensity = 1, bool onesided = true)
 {
     quad          = q;
     Lemit         = l * intensity;
     this.onesided = onesided;
 }