Exemple #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;
                }
            }
        }
Exemple #2
0
        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];
            }
        }