Пример #1
0
        public Color renderPixel(Scene scene, Camera cam, float x_, float y_)
        {
            if (1 == m_iMultiSamples)
            {
                return(RayTracer.TraceRay(cam.Pos, cam.PerspectiveRayDir(x_, y_), scene, 0));
            }
            Color color = Color.Black();
            float delta = 1.0f / ((float)Math.Sqrt(m_iMultiSamples));
            int   count = 0;

            for (float x = x_ - 0.5f; x < x_ + 0.5f; x += delta)
            {
                for (float y = y_ - 0.5f; y < y_ + 0.5f; y += delta)
                {
                    color += RayTracer.TraceRay(cam.Pos, cam.PerspectiveRayDir(x, y), scene, 0);
                    ++count;
                }
            }
            return(color * (1.0f / m_iMultiSamples));
        }
Пример #2
0
        private void RenderLoop(object boxedToken)
        {
            var cancellationToken = (CancellationToken)boxedToken;

            // Create a ray tracer, and create a reference to "sphere2" that we are going to bounce
            var rayTracer = new RayTracer(_width, _height);
            var scene     = rayTracer._defaultScene;
            var sphere2   = (Sphere)scene.Things[0]; // The first item is assumed to be our sphere
            var baseY     = sphere2.Radius;

            sphere2.Center.Y = sphere2.Radius;

            // Timing determines how fast the ball bounces as well as diagnostics frames/second info
            var renderingTime = new Stopwatch();
            var totalTime     = Stopwatch.StartNew();

            // Keep rendering until the rendering task has been canceled
            while (!cancellationToken.IsCancellationRequested)
            {
                // Get the next buffer
                var rgb = _freeBuffers.GetObject();

                // Determine the new position of the sphere based on the current time elapsed
                double dy2 = 0.8 * Math.Abs(Math.Sin(totalTime.ElapsedMilliseconds * Math.PI / 3000));
                sphere2.Center.Y = baseY + dy2;

                // Render the scene
                renderingTime.Reset();
                renderingTime.Start();

                var options = new ParallelOptions
                {
                    MaxDegreeOfParallelism = _degreeOfParallelism,
                    CancellationToken      = _cancellation.Token
                };
                if (!_isParallel)
                {
                    rayTracer.RenderSequential(scene, rgb);
                }
                else if (_showThreads)
                {
                    rayTracer.RenderParallelShowingThreads(scene, rgb, options);
                }
                else
                {
                    rayTracer.RenderParallel(scene, rgb, options);
                }

                renderingTime.Stop();

                // Update the bitmap in the UI thread
                //var framesPerSecond = (++frame * 1000.0 / renderingTime.ElapsedMilliseconds);
                var framesPerSecond = 1000.0 / renderingTime.ElapsedMilliseconds;
                BeginInvoke((Action) delegate
                {
                    // Copy the pixel array into the bitmap
                    var bmpData = _bitmap.LockBits(_rect, ImageLockMode.WriteOnly, _bitmap.PixelFormat);
                    Marshal.Copy(rgb, 0, bmpData.Scan0, rgb.Length);
                    _bitmap.UnlockBits(bmpData);
                    _freeBuffers.PutObject(rgb);

                    // Refresh the UI
                    _renderedImage.Invalidate();
                    Text = $"Ray Tracer - FPS: {framesPerSecond:F1}";
                });
            }
        }