コード例 #1
0
        public void TreadSafeSamplerReturnsAllItsElementsForEachThread()
        {
            const int samplesCount = 100;

            List <int> Generator(int count) => Enumerable.Range(0, count).ToList();

            ThreadSafeSampler <int> sampler = new ThreadSafeSampler <int>(Generator, samplesCount);
            List <int> allSamples           = Generator(samplesCount);

            Parallel.For(0, 1000, _ =>
            {
                List <int> returnedSamples = Enumerable.Range(0, samplesCount).Select(i => sampler.Sample).ToList();

                returnedSamples.Should().BeEquivalentTo(allSamples);
            });
        }
コード例 #2
0
        public void TreadSafeSamplerShouldBeThreadSafe()
        {
            const int samplesCount = 1;

            List <int> Generator(int count) => Enumerable.Range(0, count).ToList();

            ThreadSafeSampler <int> sampler = new ThreadSafeSampler <int>(Generator, samplesCount);

            Action action = () =>
            {
                Parallel.For(0, 1000, _ =>
                {
                    for (; _ < 1000; _++)
                    {
                        sampler.GetSample();
                    }
                });
            };

            action.Should().NotThrow();
        }
コード例 #3
0
        public override void Render(Scene scene, Camera camera)
        {
            scene.Preprocess();

            if (camera is LensCamera lensCamera && lensCamera.AutoFocus)
            {
                var ray     = lensCamera.GetRay(0.5f, 0.5f);
                var hitInfo = new HitInfo();
                var hit     = scene.HitTest(ray, ref hitInfo, 0.001f, float.PositiveInfinity);
                if (hit)
                {
                    lensCamera.FocusDistance = hitInfo.Distance;
                }
                else
                {
                    lensCamera.FocusDistance = 100000f;
                }
            }

            int width  = Resolution;
            int height = (int)(width / camera.AspectRatio);
            var image  = new Texture(width, height);
            AbstractSampler <Vector2> sampler = new ThreadSafeSampler <Vector2>(Sampling, Samples);

            for (int k = 0; k < Samples; k++)
            {
                try
                {
                    Parallel.For(0, width, new ParallelOptions {
                        CancellationToken = CancellationToken
                    }, i =>
                    {
                        for (int j = 0; j < height; j++)
                        {
                            var sample = sampler.GetSample(k);
                            float u    = (i + sample.X) / (width - 1);
                            float v    = (j + sample.Y) / (height - 1);
                            Ray ray    = camera.GetRay(u, v);
                            var shade  = Shade(ray, scene, MaxDepth);
                            image.Bloom(shade, i, j, (int)shade.GetBrightness(), Bloom);
                            image[i, j] += shade;
                        }
                    });
                }
                catch (Exception e)
                {
                    Log.Warn(e);
                }

                if (CancellationToken.IsCancellationRequested)
                {
                    return;
                }

                if (k % SamplesRenderStep == 0 || k == Samples - 1)
                {
                    var output = new Texture(image);
                    output.Process(c => (c / (k + 1)).Clamp());
                    if (GammaCorrection)
                    {
                        output.AutoGammaCorrect();
                    }
                    var percentage = (k + 1) * 100 / Samples;
                    OnFrameReady?.Invoke(percentage, output);
                }
            }
        }