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 AddSplat(Point2D p, Spectrum v) { //ProfilePhase pp(Prof::SplatFilm); if (v.HasNaNs()) { //LOG(ERROR) << StringPrintf("Ignoring splatted spectrum with NaN values " //"at (%f, %f)", p.x, p.y); return; } else if (v.Y() < 0.0) { //LOG(ERROR) << StringPrintf("Ignoring splatted spectrum with negative " //"luminance %f at (%f, %f)", v.y(), p.x, p.y); return; } else if (double.IsInfinity(v.Y())) { //LOG(ERROR) << StringPrintf("Ignoring splatted spectrum with infinite " //"luminance at (%f, %f)", p.x, p.y); return; } if (!p.ToPoint2I().InsideExclusive(CroppedPixelBounds)) { return; } if (v.Y() > _maxSampleLuminance) { v *= _maxSampleLuminance / v.Y(); } double[] xyz = v.ToXyz(); Pixel pixel = GetPixel(p.ToPoint2I()); for (int i = 0; i < 3; ++i) { pixel.splatXYZ[i] += xyz[i]; } }