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; } } }
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; } } }