Пример #1
0
        public override Color[,] RenderScene(Scene scene, Camera camera, Action <float> updateProcessCallback)
        {
            progress = 0;
            //Parallel.For(0, height, y =>
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Vector3 colorValue = Vector3.Zero;
                    for (int i = 0; i < samples; i++)
                    {
                        float xLerp = (float)(x + random.NextDouble()) / width;
                        float yLerp = (float)(y + random.NextDouble()) / height;
                        Ray   ray   = camera.GetRay(xLerp, yLerp);
                        colorValue += GetColorValue(ray, scene, 0);
                    }

                    colorValue /= samples;
                    colorValue  = Vector3.Clamp(colorValue, Vector3.Zero, Vector3.One);
                    // Gamma 2
                    colorValue.X = MathF.Sqrt(colorValue.X);
                    colorValue.Y = MathF.Sqrt(colorValue.Y);
                    colorValue.Z = MathF.Sqrt(colorValue.Z);

                    colors[x, height - y - 1] = Color.FromArgb((int)(255 * colorValue.X), (int)(255 * colorValue.Y), (int)(255 * colorValue.Z));


                    progress += (float)1 / height / width;
                    if (progress > 1)
                    {
                        progress = 1;
                    }
                    updateProcessCallback?.Invoke(progress);
                }
            }
            updateProcessCallback?.Invoke(1);
            return(colors);
        }
Пример #2
0
        private void SaveFile()
        {
            int scannedPixels = 0;

            Parallel.For(0, Height, new ParallelOptions()
            {
                MaxDegreeOfParallelism = 1
            }, (k) =>
            {
                int j = Height - k;
                for (int i = 0; i < Width; i++)
                {
                    Vector3 color = Vector3.Zero;
                    for (int s = 0; s < samplesPerPixel; s++)
                    {
                        var u = (float)(i + Utils.Rand.NextDouble()) / (Width - 1);
                        var v = (float)(j + Utils.Rand.NextDouble()) / (Height - 1);

                        Ray r  = Camera.GetRay(u, v);
                        color += r.RayColor(EngineObjects, SceneLights, maxDepth);
                    }
                    //System.Threading.Interlocked.Increment(ref scannedPixels);
                    //var tmp = MathF.Round((float)scannedPixels / ColorBuffer.Length * 100);
                    //Console.WriteLine(tmp.ToString().Replace(',', '.') + " %");
                    ColorBuffer[(k * Width) + i] = color;
                }
            });
            using StreamWriter sw = new StreamWriter(outputFilePath);
            sw.WriteLine("P3");
            sw.WriteLine($"{Width} {Height}");
            sw.WriteLine("255");
            for (int i = 0; i < ColorBuffer.Length; i++)
            {
                sw.WriteColor(ColorBuffer[i], samplesPerPixel);
            }
            sw.Flush();
            Console.WriteLine("Done!");
        }
Пример #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);
                }
            }
        }