示例#1
0
文件: Window.cs 项目: merwaaan/pbrt
        // Update the texture with a portion of the given film.
        public void UpdateTileFromFilm(Bounds2 <int> tileBounds, Film film)
        {
            foreach (var posFilm in tileBounds.IteratePoints())
            {
                if (posFilm.X >= 0 && posFilm.X < Program.Width && posFilm.Y >= 0 && posFilm.Y < Program.Height)
                {
                    var pixel = film.GetPixel(posFilm);
                    var color = pixel.contribSum / pixel.filterWeightSum;

                    var offset = (posFilm.Y * Width + posFilm.X) * 4; // BGRA
                    bitmap[offset + 0] = (byte)Math.Min(255, color.B * 255);
                    bitmap[offset + 1] = (byte)Math.Min(255, color.G * 255);
                    bitmap[offset + 2] = (byte)Math.Min(255, color.R * 255);
                }
            }
        }
示例#2
0
        public override void Render(Scene scene, Camera camera, IWindow window)
        {
            Preprocess(scene);

            // Compute the number of tiles to use

            var sampleBounds = camera.Film.GetSampleBounds();
            var sampleExtent = sampleBounds.Diagonal();

            var nTiles = new Vector2 <int>(
                (sampleExtent.X + Program.TileSize - 1) / Program.TileSize,
                (sampleExtent.Y + Program.TileSize - 1) / Program.TileSize);

            // Render tiles in parallel

            //Parallel.For(0, nTiles.X * nTiles.Y, tile =>
            Parallel.For(0, nTiles.X * nTiles.Y, new ParallelOptions {
                MaxDegreeOfParallelism = Program.ThreadCount
            }, tile =>
            {
                var tileX = tile % nTiles.X;
                var tileY = tile / nTiles.X;

                // Get a sampler instance for the current tile
                var seed        = tileY * nTiles.X + tileX;
                var tileSampler = Sampler.Clone(seed);

                // Compute the extent of pixels to be sampled in this tile
                var x0         = sampleBounds.Min.X + tileX * Program.TileSize;
                var x1         = Math.Min(x0 + Program.TileSize, sampleBounds.Max.X);
                var y0         = sampleBounds.Min.Y + tileY * Program.TileSize;
                var y1         = Math.Min(y0 + Program.TileSize, sampleBounds.Max.Y);
                var tileBounds = new Bounds2 <int>(new Point2 <int>(x0, y0), new Point2 <int>(x1, y1));

                var filmTile = camera.Film.GetTile(tileBounds);
                MarkTile(tileBounds);

                // Loop over the pixels in the tile
                foreach (var pixel in tileBounds.IteratePoints())
                {
                    tileSampler.StartPixel(pixel);
                    do
                    {
                        var cameraSample = tileSampler.GetCameraSample(pixel);
                        if (pixel.X == 48 && pixel.Y == 209)
                        {
                        }
                        // Generate a camera ray for the current sample
                        var rayWeight = camera.GenerateRayDifferential(cameraSample, out RayDifferential ray);
                        ray.ScaleDifferentials((float)(1.0f / Math.Sqrt(tileSampler.SamplesPerPixel)));

                        // Evaluate radiance along the camera ray
                        var L = Spectrum.Zero;
                        if (rayWeight > 0)
                        {
                            L = Li(ray, scene, camera, tileSampler);
                        }

                        // TODO check invalid radiance

                        // Add the ray's contribution to the image
                        filmTile.AddSample(cameraSample.PosFilm, L, rayWeight);
                    } while (tileSampler.StartNextSample());
                }

                // Merge the tile into the film
                camera.Film.MergeTile(filmTile);

                //Thread.Sleep(100);
                UnmarkTile(tileBounds);
                UpdateTileFromFilm(tileBounds, camera.Film);
            });
        }