Ejemplo n.º 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;
        }
Ejemplo n.º 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;
        }
Ejemplo n.º 3
0
        public RayDifferential TransformRayDifferential(RayDifferential r)
        {
            var ret = r.Clone();

            ret.Origin      = TransformPoint(ref r.Origin);
            ret.Direction   = TransformVector(ref r.Direction);
            ret.RxOrigin    = TransformPoint(ref r.RxOrigin);
            ret.RyOrigin    = TransformPoint(ref r.RyOrigin);
            ret.RxDirection = TransformVector(ref r.RxDirection);
            ret.RyDirection = TransformVector(ref r.RyDirection);
            return(ret);
        }
Ejemplo n.º 4
0
        public static Spectrum SpecularTransmit(RayDifferential ray, Bsdf bsdf,
            Random rng, Intersection isect, Renderer renderer,
            Scene scene, Sample sample)
        {
            Vector wo = -ray.Direction, wi;
            float pdf;
            Point p = bsdf.DgShading.Point;
            Normal n = bsdf.DgShading.Normal;
            Spectrum f = bsdf.SampleF(wo, out wi, new BsdfSample(rng), out pdf,
                BxdfType.Transmission | BxdfType.Specular);
            Spectrum L = Spectrum.CreateBlack();
            if (pdf > 0.0f && !f.IsBlack && Vector.AbsDot(wi, n) != 0.0f)
            {
                // Compute ray differential _rd_ for specular transmission
                var rd = new RayDifferential(p, wi, ray, isect.RayEpsilon);
                if (ray.HasDifferentials)
                {
                    rd.HasDifferentials = true;
                    rd.RxOrigin = p + isect.DifferentialGeometry.DpDx;
                    rd.RyOrigin = p + isect.DifferentialGeometry.DpDy;

                    float eta = bsdf.Eta;
                    Vector w = -wo;
                    if (Vector.Dot(wo, n) < 0)
                        eta = 1.0f / eta;

                    Normal dndx = bsdf.DgShading.DnDu * bsdf.DgShading.DuDx +
                        bsdf.DgShading.DnDv * bsdf.DgShading.DvDx;
                    Normal dndy = bsdf.DgShading.DnDu * bsdf.DgShading.DuDy +
                        bsdf.DgShading.DnDv * bsdf.DgShading.DvDy;

                    Vector dwodx = -ray.RxDirection - wo, dwody = -ray.RyDirection - wo;
                    float dDNdx = Vector.Dot(dwodx, n) + Vector.Dot(wo, dndx);
                    float dDNdy = Vector.Dot(dwody, n) + Vector.Dot(wo, dndy);

                    float mu = eta * Vector.Dot(w, n) - Vector.Dot(wi, n);
                    float dmudx = (eta - (eta * eta * Vector.Dot(w, n)) / Vector.Dot(wi, n)) * dDNdx;
                    float dmudy = (eta - (eta * eta * Vector.Dot(w, n)) / Vector.Dot(wi, n)) * dDNdy;

                    rd.RxDirection = wi + eta * dwodx - (Vector) (mu * dndx + dmudx * n);
                    rd.RyDirection = wi + eta * dwody - (Vector) (mu * dndy + dmudy * n);
                }
                Spectrum Li = renderer.Li(scene, rd, sample, rng);
                L = f * Li * Vector.AbsDot(wi, n) / pdf;
            }
            return L;
        }
Ejemplo n.º 5
0
        public override Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray, Intersection intersection,
            Sample sample, Random rng)
        {
            Spectrum L = Spectrum.CreateBlack();
            // Compute emitted and reflected light at ray intersection point

            // Evaluate BSDF at hit point
            var bsdf = intersection.GetBsdf(ray);

            // Initialize common variables for Whitted integrator
            Point p = bsdf.DgShading.Point;
            Normal n = bsdf.DgShading.Normal;
            Vector wo = -ray.Direction;

            // Compute emitted light if ray hit an area light source
            L += intersection.Le(wo);

            // Add contribution of each light source
            foreach (var light in scene.Lights)
            {
                Vector wi;
                float pdf;
                VisibilityTester visibility;
                Spectrum Li = light.SampleL(p, intersection.RayEpsilon,
                    new LightSample(rng), ray.Time, out wi, out pdf, out visibility);
                if (Li.IsBlack || pdf == 0.0f)
                    continue;
                Spectrum f = bsdf.F(wo, wi);
                if (!f.IsBlack && visibility.Unoccluded(scene))
                    L += f * Li * Vector.AbsDot(wi, n)
                        * visibility.Transmittance(scene, renderer, sample, rng)
                        / pdf;
            }
            if (ray.Depth + 1 < _maxDepth)
            {
                // Trace rays for specular reflection and refraction
                L += IntegratorUtilities.SpecularReflect(ray, bsdf, rng, intersection, renderer, scene, sample);
                L += IntegratorUtilities.SpecularTransmit(ray, bsdf, rng, intersection, renderer, scene, sample);
            }
            return L;
        }
Ejemplo n.º 6
0
        public RayDifferential TransformRayDifferential(RayDifferential r)
        {
            RayDifferential tr;

            if (!_actuallyAnimated || r.Time <= _startTime)
            {
                tr = _startTransform.TransformRayDifferential(r);
            }
            else if (r.Time >= _endTime)
            {
                tr = _endTransform.TransformRayDifferential(r);
            }
            else
            {
                Transform t;
                Interpolate(r.Time, out t);
                tr = t.TransformRayDifferential(r);
            }
            tr.Time = r.Time;
            return(tr);
        }
Ejemplo n.º 7
0
        public void ComputeDifferentials(RayDifferential ray)
        {
            if (ray.HasDifferentials)
            {
                // Estimate screen space change in $\pt{}$ and $(u,v)$

                // Compute auxiliary intersection points with plane
                float d = -Normal.Dot(Normal, new Vector(Point.X, Point.Y, Point.Z));
                var rxv = new Vector(ray.RxOrigin.X, ray.RxOrigin.Y, ray.RxOrigin.Z);
                float tx = -(Normal.Dot(Normal, rxv) + d) / Normal.Dot(Normal, ray.RxDirection);
                if (float.IsNaN(tx))
                    throw new InvalidOperationException();
                Point px = ray.RxOrigin + tx * ray.RxDirection;
                var ryv = new Vector(ray.RyOrigin.X, ray.RyOrigin.Y, ray.RyOrigin.Z);
                float ty = -(Normal.Dot(Normal, ryv) + d) / Normal.Dot(Normal, ray.RyDirection);
                if (float.IsNaN(ty))
                    throw new InvalidOperationException();
                Point py = ray.RyOrigin + ty * ray.RyDirection;
                DpDx = px - Point;
                DpDy = py - Point;

                // Compute $(u,v)$ offsets at auxiliary points

                // Initialize _A_, _Bx_, and _By_ matrices for offset computation
                var A = new float[2, 2];
                var Bx = new float[2];
                var By = new float[2];
                var axes = new int[2];
                if (Math.Abs(Normal.X) > Math.Abs(Normal.Y) && Math.Abs(Normal.X) > Math.Abs(Normal.Z))
                {
                    axes[0] = 1;
                    axes[1] = 2;
                }
                else if (Math.Abs(Normal.Y) > Math.Abs(Normal.Z))
                {
                    axes[0] = 0;
                    axes[1] = 2;
                }
                else
                {
                    axes[0] = 0;
                    axes[1] = 1;
                }

                // Initialize matrices for chosen projection plane
                A[0, 0] = DpDu[axes[0]];
                A[0, 1] = DpDv[axes[0]];
                A[1, 0] = DpDu[axes[1]];
                A[1, 1] = DpDv[axes[1]];
                Bx[0] = px[axes[0]] - Point[axes[0]];
                Bx[1] = px[axes[1]] - Point[axes[1]];
                By[0] = py[axes[0]] - Point[axes[0]];
                By[1] = py[axes[1]] - Point[axes[1]];
                if (!Matrix4x4.SolveLinearSystem2x2(A, Bx, out DuDx, out DvDx))
                {
                    DuDx = 0.0f;
                    DvDx = 0.0f;
                }
                if (!Matrix4x4.SolveLinearSystem2x2(A, By, out DuDy, out DvDy))
                {
                    DuDy = 0.0f;
                    DvDy = 0.0f;
                }
            }
            else
            {
                DuDx = DvDx = 0.0f;
                DuDy = DvDy = 0.0f;
                DpDx = DpDy = Vector.Zero;
            }
        }
Ejemplo n.º 8
0
 public abstract Spectrum Transmittance(Scene scene, RayDifferential ray, Sample sample,
     Random rng);
Ejemplo n.º 9
0
 public Spectrum Li(Scene scene, RayDifferential ray, Sample sample, Random rng)
 {
     Intersection intersection = null;
     Spectrum t;
     return Li(scene, ray, sample, rng, ref intersection, out t);
 }
Ejemplo n.º 10
0
 public abstract Spectrum Li(Scene scene, RayDifferential ray, Sample sample, Random rng,
     ref Intersection intersection, out Spectrum t);
Ejemplo n.º 11
0
 public virtual Spectrum Le(RayDifferential r)
 {
     return Spectrum.CreateBlack();
 }
Ejemplo n.º 12
0
 public RayDifferential TransformRayDifferential(RayDifferential r)
 {
     RayDifferential tr;
     if (!_actuallyAnimated || r.Time <= _startTime)
         tr = _startTransform.TransformRayDifferential(r);
     else if (r.Time >= _endTime)
         tr = _endTransform.TransformRayDifferential(r);
     else
     {
         Transform t;
         Interpolate(r.Time, out t);
         tr = t.TransformRayDifferential(r);
     }
     tr.Time = r.Time;
     return tr;
 }
Ejemplo n.º 13
0
 public override Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray, Sample sample, Random rng, out Spectrum transmittance)
 {
     // TODO
     transmittance = new Spectrum(1.0f);
     return Spectrum.CreateBlack();
 }
Ejemplo n.º 14
0
        private Task CreateRenderTask(
            Scene scene, Sample origSample, CancellationToken cancellationToken,
            int taskNumber, int taskCount)
        {
            return new Task(() =>
            {
                var sampler = _sampler.GetSubSampler(taskNumber, taskCount);
                if (sampler == null)
                    return;

                var rng = new Random(taskNumber);

                // Allocate space for samples and intersections
                int maxSamples = _sampler.MaximumSampleCount;
                var samples = origSample.Duplicate(maxSamples);
                var rays = new RayDifferential[maxSamples];
                var Ls = new Spectrum[maxSamples];
                var Ts = new Spectrum[maxSamples];
                var isects = new Intersection[maxSamples];

                // Get samples from _Sampler_ and update image
                int sampleCount;
                while ((sampleCount = sampler.GetMoreSamples(samples, rng)) > 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    // Generate camera rays and compute radiance along rays
                    for (int i = 0; i < sampleCount; ++i)
                    {
                        // Find camera ray for _sample[i]_
                        float rayWeight = _camera.GenerateRayDifferential(samples[i], out rays[i]);
                        rays[i].ScaleDifferentials(1.0f / MathUtility.Sqrt(sampler.SamplesPerPixel));

                        // Evaluate radiance along camera ray
                        if (rayWeight > 0.0f)
                        {
                            Ls[i] = rayWeight * Li(scene, rays[i], samples[i], rng, ref isects[i], out Ts[i]);
                        }
                        else
                        {
                            Ls[i] = new Spectrum(0.0f);
                            Ts[i] = new Spectrum(1.0f);
                        }
                    }

                    // Report sample results to _Sampler_, add contributions to image
                    if (sampler.ReportResults(samples, rays, Ls, isects, sampleCount))
                        for (int i = 0; i < sampleCount; ++i)
                            _camera.Film.AddSample(samples[i], Ls[i]);
                }

                _camera.Film.UpdateDisplay(
                    sampler.XStart, sampler.YStart,
                    sampler.XEnd + 1, sampler.YEnd + 1);
            }, cancellationToken);
        }
Ejemplo n.º 15
0
 public override Spectrum Transmittance(Scene scene, RayDifferential ray, Sample sample, Random rng)
 {
     return _volumeIntegrator.Transmittance(scene, this, ray, sample, rng);
 }
Ejemplo n.º 16
0
 public override Spectrum Li(Scene scene, RayDifferential ray, Sample sample, Random rng, ref Intersection intersection, out Spectrum t)
 {
     Debug.Assert(ray.Time == sample.Time);
     Spectrum Li = Spectrum.CreateBlack();
     if (scene.TryIntersect(ray, ref intersection))
         Li = _surfaceIntegrator.Li(scene, this, ray, intersection, sample, rng);
     else
     {
         // Handle ray that doesn't intersect any geometry
         foreach (var light in scene.Lights)
             Li += light.Le(ray);
     }
     Spectrum Lvi = _volumeIntegrator.Li(scene, this, ray, sample, rng, out t);
     return t * Li + Lvi;
 }
Ejemplo n.º 17
0
 public virtual bool ReportResults(Sample[] samples, RayDifferential[] rays,
     Spectrum[] ls, Intersection[] intersections, int count)
 {
     return true;
 }
Ejemplo n.º 18
0
 public Bssrdf GetBssrdf(RayDifferential ray)
 {
     _dg.ComputeDifferentials(ray);
     return _primitive.GetBssrdf(_dg, ObjectToWorld);
 }
Ejemplo n.º 19
0
 public override Spectrum Transmittance(Scene scene, Renderer renderer, RayDifferential ray, Sample sample, Random rng)
 {
     // TODO
     return new Spectrum(1.0f);
 }
Ejemplo n.º 20
0
 public RayDifferential TransformRayDifferential(RayDifferential r)
 {
     var ret = r.Clone();
     ret.Origin = TransformPoint(ref r.Origin);
     ret.Direction = TransformVector(ref r.Direction);
     ret.RxOrigin = TransformPoint(ref r.RxOrigin);
     ret.RyOrigin = TransformPoint(ref r.RyOrigin);
     ret.RxDirection = TransformVector(ref r.RxDirection);
     ret.RyDirection = TransformVector(ref r.RyDirection);
     return ret;
 }
Ejemplo n.º 21
0
 public abstract Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray,
     Sample sample, Random rng, out Spectrum transmittance);
Ejemplo n.º 22
0
 public abstract Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray,
     Intersection intersection, Sample sample, Random rng);