示例#1
0
        public virtual float GenerateRayDifferential(CameraSample sample, out RayDifferential rd)
        {
            Ray ray;
            float wt = GenerateRay(sample, out ray);
            rd = RayDifferential.FromRay(ray);

            // Find ray after shifting one pixel in the $x$ direction
            CameraSample sshift = sample;
            ++(sshift.ImageX);
            Ray rx;
            float wtx = GenerateRay(sshift, out rx);
            rd.RxOrigin = rx.Origin;
            rd.RxDirection = rx.Direction;

            // Find ray after shifting one pixel in the $y$ direction
            --(sshift.ImageX);
            ++(sshift.ImageY);
            Ray ry;
            float wty = GenerateRay(sshift, out ry);
            rd.RyOrigin = ry.Origin;
            rd.RyDirection = ry.Direction;

            if (wtx == 0.0f || wty == 0.0f)
                return 0.0f;

            rd.HasDifferentials = true;
            return wt;
        }
示例#2
0
        public override float GenerateRayDifferential(CameraSample sample, out RayDifferential ray)
        {
            // Generate raster and camera samples
            Point Pras = new Point(sample.ImageX, sample.ImageY, 0);
            Point Pcamera = RasterToCamera.TransformPoint(ref Pras);
            ray = new RayDifferential(new Point(0, 0, 0), Vector.Normalize((Vector) Pcamera), 0.0f);
            // Modify ray for depth of field
            if (LensRadius > 0.0f)
            {
                // Sample point on lens
                float lensU, lensV;
                MonteCarloUtilities.ConcentricSampleDisk(sample.LensU, sample.LensV, out lensU, out lensV);
                lensU *= LensRadius;
                lensV *= LensRadius;

                // Compute point on plane of focus
                float ft = FocalDistance / ray.Direction.Z;
                Point Pfocus = ray.Evaluate(ft);

                // Update ray for effect of lens
                ray.Origin = new Point(lensU, lensV, 0.0f);
                ray.Direction = Vector.Normalize(Pfocus - ray.Origin);
            }
            // Compute offset rays for _PerspectiveCamera_ ray differentials
            ray.RxOrigin = ray.RyOrigin = ray.Origin;
            ray.RxDirection = Vector.Normalize((Vector) Pcamera + _dxCamera);
            ray.RyDirection = Vector.Normalize((Vector) Pcamera + _dyCamera);
            ray.Time = sample.Time;
            ray = CameraToWorld.TransformRayDifferential(ray);
            return 1.0f;
        }
示例#3
0
        public override void AddSample(CameraSample sample, Spectrum l)
        {
            // Compute sample's raster extent
            float dimageX = sample.ImageX - 0.5f;
            float dimageY = sample.ImageY - 0.5f;
            int x0 = MathUtility.Ceiling(dimageX - _filter.XWidth);
            int x1 = MathUtility.Floor(dimageX + _filter.XWidth);
            int y0 = MathUtility.Ceiling(dimageY - _filter.YWidth);
            int y1 = MathUtility.Floor(dimageY + _filter.YWidth);
            x0 = Math.Max(x0, _xPixelStart);
            x1 = Math.Min(x1, _xPixelStart + _xPixelCount - 1);
            y0 = Math.Max(y0, _yPixelStart);
            y1 = Math.Min(y1, _yPixelStart + _yPixelCount - 1);
            if ((x1 - x0) < 0 || (y1 - y0) < 0)
                return;

            // Loop over filter support and add sample to pixel arrays
            var xyz = l.ToXyz();

            // Precompute $x$ and $y$ filter table offsets
            var ifx = new int[x1 - x0 + 1];
            for (int x = x0; x <= x1; ++x)
            {
                float fx = Math.Abs((x - dimageX) * _filter.InverseXWidth * FilterTableSize);
                ifx[x - x0] = Math.Min(MathUtility.Floor(fx), FilterTableSize - 1);
            }
            var ify = new int[y1 - y0 + 1];
            for (int y = y0; y <= y1; ++y)
            {
                float fy = Math.Abs((y - dimageY) * _filter.InverseYWidth * FilterTableSize);
                ify[y - y0] = Math.Min(MathUtility.Floor(fy), FilterTableSize - 1);
            }
            bool syncNeeded = (_filter.XWidth > 0.5f || _filter.YWidth > 0.5f);
            for (int y = y0; y <= y1; ++y)
            {
                for (int x = x0; x <= x1; ++x)
                {
                    // Evaluate filter value at $(x,y)$ pixel
                    int offset = ify[y - y0] * FilterTableSize + ifx[x - x0];
                    float filterWt = _filterTable[offset];

                    // Update pixel values with filtered sample contribution
                    var pixel = _pixels[x - _xPixelStart, y - _yPixelStart];
                    if (!syncNeeded)
                    {
                        pixel.Lxyz[0] += filterWt * xyz[0];
                        pixel.Lxyz[1] += filterWt * xyz[1];
                        pixel.Lxyz[2] += filterWt * xyz[2];
                        pixel.WeightSum += filterWt;
                    }
                    else
                    {
                        // Safely update _Lxyz_ and _weightSum_ even with concurrency
                        AtomicAdd(ref pixel.Lxyz[0], filterWt * xyz[0]);
                        AtomicAdd(ref pixel.Lxyz[1], filterWt * xyz[1]);
                        AtomicAdd(ref pixel.Lxyz[2], filterWt * xyz[2]);
                        AtomicAdd(ref pixel.WeightSum, filterWt);
                    }
                }
            }
        }
示例#4
0
 public override void Splat(CameraSample sample, Spectrum l)
 {
     var xyz = l.ToXyz();
     int x = MathUtility.Floor(sample.ImageX), y = MathUtility.Floor(sample.ImageY);
     if (x < _xPixelStart || x - _xPixelStart >= _xPixelCount ||
         y < _yPixelStart || y - _yPixelStart >= _yPixelCount) return;
     var pixel = _pixels[x - _xPixelStart, y - _yPixelStart];
     AtomicAdd(ref pixel.SplatXyz[0], xyz[0]);
     AtomicAdd(ref pixel.SplatXyz[1], xyz[1]);
     AtomicAdd(ref pixel.SplatXyz[2], xyz[2]);
 }
示例#5
0
 public abstract float GenerateRay(CameraSample sample, out Ray ray);
示例#6
0
 /// Updates the stored image. Splatted values are summed, rather than
 /// a weighted average as is the case with AddSample.
 public abstract void Splat(CameraSample sample, Spectrum l);
示例#7
0
 /// Updates the stored image with a given sample and corresponding radiance.
 /// The selected reconstruction filter will be applied.
 public abstract void AddSample(CameraSample sample, Spectrum l);