Esempio n. 1
0
        public void Render()
        {
            Scene   scene   = Scene;
            Camera  camera  = Camera;
            Sampler sampler = Sampler;
            Buffer  buf     = PBuffer;

            (int w, int h) = (buf.W, buf.H);
            int spp     = SamplesPerPixel;
            int sppRoot = (int)(Math.Sqrt(SamplesPerPixel));

            scene.Compile();
            scene.rays = 0;
            Random rand = new Random();
            double fu, fv;

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    if (StratifiedSampling)
                    {
                        for (int u = 0; u < sppRoot; u++)
                        {
                            for (int v = 0; v < sppRoot; v++)
                            {
                                fu = (u + 0.5) / sppRoot;
                                fv = (v + 0.5) / sppRoot;
                                Ray    ray    = camera.CastRay(x, y, w, h, fu, fv, rand);
                                Colour sample = sampler.Sample(scene, ray, rand);
                                buf.AddSample(x, y, sample);
                            }
                        }
                    }
                    else
                    {
                        // Random subsampling
                        for (int ii = 0; ii < spp; ii++)
                        {
                            fu = rand.NextDouble();
                            fv = rand.NextDouble();
                            Ray    ray    = camera.CastRay(x, y, w, h, fu, fv, rand);
                            Colour sample = sampler.Sample(scene, ray, rand);
                            buf.AddSample(x, y, sample);
                        }
                    }
                    // Adaptive Sampling
                    if (AdaptiveSamples > 0)
                    {
                        double v = buf.StandardDeviation(x, y).MaxComponent();
                        v = Util.Clamp(v / AdaptiveThreshold, 0, 1);
                        v = Math.Pow(v, AdaptiveExponent);
                        int samples = (int)(v * AdaptiveSamples);
                        for (int d = 0; d < samples; d++)
                        {
                            fu = rand.NextDouble();
                            fv = rand.NextDouble();
                            Ray    ray    = camera.CastRay(x, y, w, h, fu, fv, rand);
                            Colour sample = sampler.Sample(scene, ray, rand);
                            buf.AddSample(x, y, sample);
                        }
                    }

                    if (FireflySamples > 0)
                    {
                        if (PBuffer.StandardDeviation(x, y).MaxComponent() > FireflyThreshold)
                        {
                            for (int e = 0; e < FireflySamples; e++)
                            {
                                fu = rand.NextDouble();
                                fv = rand.NextDouble();
                                Ray    ray    = camera.CastRay(x, y, w, h, fu, fv, rand);
                                Colour sample = sampler.Sample(scene, ray, rand);
                                PBuffer.AddSample(x, y, sample);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 2
0
 public static Material LightMaterial(Colour color, double emittance)
 {
     return(new Material(color, null, null, null, null, 1, emittance, 1, 0, 0, -1, false));
 }
Esempio n. 3
0
        public void RenderParallel()
        {
            Scene   scene   = Scene;
            Camera  camera  = Camera;
            Sampler sampler = Sampler;
            Buffer  buf     = PBuffer;

            (int w, int h) = (buf.W, buf.H);
            int spp     = SamplesPerPixel;
            int sppRoot = (int)(Math.Sqrt(SamplesPerPixel));

            scene.Compile();
            scene.rays = 0;

            // Stop watch timer
            Stopwatch sw = new Stopwatch();

            sw.Start();

            // Random Number Generator from on Math.Numerics
            System.Random rand = new SystemRandomSource(sw.Elapsed.Milliseconds, true);

            // Frame resolution
            int totalPixels = h * w;

            // Create a cancellation token for Parallel.For loop control
            CancellationTokenSource cts = new CancellationTokenSource();

            // ParallelOptions for Parallel.For
            ParallelOptions po = new ParallelOptions();

            po.CancellationToken = cts.Token;

            // Set number of cores/threads
            po.MaxDegreeOfParallelism = Environment.ProcessorCount;

            Console.WriteLine("{0} x {1} pixels, {2} spp, {3} core(s)", w, h, spp, po.MaxDegreeOfParallelism);

            if (StratifiedSampling)
            {
                _ = Parallel.For(0, w * h, po, (i, loopState) =>
                {
                    int y = i / w, x = i % w;
                    for (int u = 0; u < sppRoot; u++)
                    {
                        for (int v = 0; v < sppRoot; v++)
                        {
                            var fu        = (u + 0.5) / sppRoot;
                            var fv        = (v + 0.5) / sppRoot;
                            Ray ray       = camera.CastRay(x, y, w, h, fu, fv, rand);
                            Colour sample = sampler.Sample(scene, ray, rand);
                            buf.AddSample(x, y, sample);
                        }
                    }
                });
                Console.WriteLine("time elapsed:" + sw.Elapsed);
            }
            else
            {
                //Random subsampling
                _ = Parallel.ForEach(Partitioner.Create(0, totalPixels), po, (range) =>
                {
                    for (int i = range.Item1; i < range.Item2; i++)
                    {
                        for (int s = 0; s < spp; s++)
                        {
                            int y      = i / w, x = i % w;
                            var fu     = ThreadSafeRandom.NextDouble(rand);
                            var fv     = ThreadSafeRandom.NextDouble(rand);
                            var ray    = camera.CastRay(x, y, w, h, fu, fv, rand);
                            var sample = sampler.Sample(scene, ray, rand);
                            buf.AddSample(x, y, sample);
                        }
                    }
                });
                Console.WriteLine("time elapsed:" + sw.Elapsed);
            }

            if (AdaptiveSamples > 0)
            {
                _ = Parallel.For(0, w * h, po, (i, loopState) =>
                {
                    int y       = i / w, x = i % w;
                    double v    = buf.StandardDeviation(x, y).MaxComponent();
                    v           = Util.Clamp(v / AdaptiveThreshold, 0, 1);
                    v           = Math.Pow(v, AdaptiveExponent);
                    int samples = (int)(v * AdaptiveSamples);
                    for (int s = 0; s < samples; s++)
                    {
                        var fu        = rand.NextDouble();
                        var fv        = rand.NextDouble();
                        Ray ray       = camera.CastRay(x, y, w, h, fu, fv, rand);
                        Colour sample = sampler.Sample(scene, ray, rand);
                        buf.AddSample(x, y, sample);
                    }
                });
            }

            if (FireflySamples > 0)
            {
                _ = Parallel.For(0, w * h, po, (i, loopState) =>
                {
                    int y = i / w, x = i % w;
                    if (PBuffer.StandardDeviation(x, y).MaxComponent() > FireflyThreshold)
                    {
                        Parallel.For(0, FireflySamples, po, (e, loop) =>
                        {
                            var fu        = rand.NextDouble();
                            var fv        = rand.NextDouble();
                            Ray ray       = camera.CastRay(x, y, w, h, fu, fv, rand);
                            Colour sample = sampler.Sample(scene, ray, rand);
                            buf.AddSample(x, y, sample);
                        });
                    }
                });
            }
            sw.Stop();
        }
Esempio n. 4
0
 public static Material TransparentMaterial(Colour color, double index, double gloss, double tint)
 {
     return(new Material(color, null, null, null, null, 1, 0, index, gloss, tint, -1, true));
 }
Esempio n. 5
0
 public static Material MetallicMaterial(Colour color, double gloss, double tint)
 {
     return(new Material(color, null, null, null, null, 1, 0, 1, gloss, tint, 1, false));
 }
Esempio n. 6
0
 public static Material GlossyMaterial(Colour color, double index, double gloss)
 {
     return(new Material(color, null, null, null, null, 1, 0, index, gloss, 0, -1, false));
 }
Esempio n. 7
0
 public static Material SpecularMaterial(Colour color, double index)
 {
     return(new Material(color, null, null, null, null, 1, 0, index, 0, 0, -1, false));
 }
Esempio n. 8
0
 public static Material DiffuseMaterial(Colour color)
 {
     return(new Material(color, null, null, null, null, 1, 0, 1, 0, 0, -1, false));
 }
Esempio n. 9
0
 public void AddSample(int x, int y, Colour sample) => Pixels[y * W + x].AddSample(sample);
Esempio n. 10
0
 public Pixel(int Samples, Colour M, Colour V)
 {
     this.Samples = Samples;
     this.M       = M;
     this.V       = V;
 }