예제 #1
0
        public void AddSample(Point2D pFilm, Spectrum L, double sampleWeight = 1.0)
        {
            //ProfilePhase _(Prof::AddFilmSample);
            if (L.Y() > MaxSampleLuminance)
            {
                L *= MaxSampleLuminance / L.Y();
            }

            // Compute sample's raster bounds
            Point2D pFilmDiscrete = pFilm - new Point2D(0.5, 0.5);
            Point2I p0            = (pFilmDiscrete - FilterRadius.ToPoint2D()).Ceiling().ToPoint2I();
            Point2I p1            = (pFilmDiscrete + FilterRadius.ToPoint2D()).Floor().ToPoint2I() + new Point2I(1, 1);

            p0 = Point2I.Max(p0, PixelBounds.MinPoint);
            p1 = Point2I.Min(p1, PixelBounds.MaxPoint);

            // Loop over filter support and add sample to pixel arrays

            // Precompute $x$ and $y$ filter table offsets
            int[] ifx = new int[p1.X - p0.X];
            for (int x = p0.X; x < p1.X; ++x)
            {
                double fx = Math.Abs((x - pFilmDiscrete.X) * InvFilterRadius.X * FilterTableSize);
                ifx[x - p0.X] = Math.Min((int)Math.Floor(fx), FilterTableSize - 1);
            }

            int[] ify = new int[p1.Y - p0.Y];
            for (int y = p0.Y; y < p1.Y; ++y)
            {
                double fy = Math.Abs((y - pFilmDiscrete.Y) * InvFilterRadius.Y * FilterTableSize);
                ify[y - p0.Y] = Math.Min((int)Math.Floor(fy), FilterTableSize - 1);
            }

            for (int y = p0.Y; y < p1.Y; ++y)
            {
                for (int x = p0.X; x < p1.X; ++x)
                {
                    // Evaluate filter value at $(x,y)$ pixel
                    int    offset       = ify[y - p0.Y] * FilterTableSize + ifx[x - p0.X];
                    double filterWeight = _filterTable[offset];

                    // Update pixel values with filtered sample contribution
                    FilmTilePixel pixel = GetPixel(new Point2I(x, y));
                    pixel.ContribSum      += L * sampleWeight * filterWeight;
                    pixel.FilterWeightSum += filterWeight;
                }
            }
        }
예제 #2
0
        public void MergeFilmTile(FilmTile tile)
        {
            //ProfilePhase p(Prof::MergeFilmTile);
            //VLOG(1) << "Merging film tile " << tile->pixelBounds;
            //std::lock_guard < std::mutex > lock (mutex) ;
            lock (_lockObject)
            {
                foreach (Point2I pixel in tile.PixelBounds.GetPoints())
                {
                    // Merge _pixel_ into _Film::pixels_
                    FilmTilePixel tilePixel  = tile.GetPixel(pixel);
                    Pixel         mergePixel = GetPixel(pixel);
                    double[]      xyz        = tilePixel.ContribSum.ToXyz();
                    for (int i = 0; i < 3; ++i)
                    {
                        mergePixel.xyz[i] += xyz[i];
                    }

                    mergePixel.filterWeightSum += tilePixel.FilterWeightSum;
                }
            }
        }