public Spectrum Transmittance(Scene scene, Renderer renderer,
     Sample sample, Random rng)
 {
     return renderer.Transmittance(
         scene, RayDifferential.FromRay(Ray),
         sample, rng);
 }
        public override void Render(Scene scene, CancellationToken cancellationToken)
        {
            // Allow integrators to do preprocessing for the scene
            _surfaceIntegrator.PreProcess(scene, _camera, this);
            _volumeIntegrator.PreProcess(scene, _camera, this);
            // Allocate and initialize _sample_
            var sample = new Sample(_sampler, _surfaceIntegrator, _volumeIntegrator, scene);

            // Create and launch _SamplerRendererTask_s for rendering image

            // Compute number of _SamplerRendererTask_s to create for rendering
            var numPixels = _camera.Film.XResolution * _camera.Film.YResolution;
            var numTasks = Math.Max(32 * Environment.ProcessorCount, numPixels / (16 * 16));
            numTasks = (int) MathUtility.RoundUpPow2((uint) numTasks);

            var renderTasks = Enumerable.Range(0, numTasks)
                .Select(i => CreateRenderTask(scene, sample, cancellationToken,
                    numTasks - 1 - i, numTasks))
                .ToArray();

            // Organise tasks such that we do several passes over the whole image,
            // of increasing quality.
            var groupedRenderTasks = renderTasks.Select((t, i) => new { t, i })
                .GroupBy(a => a.i % 6, a => a.t)
                .ToArray();
            foreach (var groupedTasks in groupedRenderTasks)
                foreach (var task in groupedTasks)
                    task.Start();

            Task.WaitAll(renderTasks, cancellationToken);

            // Clean up after rendering and store final image
            _camera.Film.WriteImage();
        }
        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);
        }
Exemple #4
0
 public BsdfSample(Sample sample, BsdfSampleOffsets offsets, int n)
 {
     Debug.Assert(n < sample.Num2D[offsets.PosOffset]);
     Debug.Assert(n < sample.Num1D[offsets.ComponentOffset]);
     UDir0 = sample.TwoD[offsets.PosOffset][2 * n];
     UDir1 = sample.TwoD[offsets.PosOffset][2 * n + 1];
     UComponent = sample.OneD[offsets.ComponentOffset][n];
     Debug.Assert(UDir0 >= 0.0f && UDir0 < 1.0f);
     Debug.Assert(UDir1 >= 0.0f && UDir1 < 1.0f);
     Debug.Assert(UComponent >= 0.0f && UComponent < 1.0f);
 }
Exemple #5
0
 public LightSample(Sample sample, LightSampleOffsets offsets, int n)
 {
     Debug.Assert(n < sample.Num2D[offsets.PosOffset]);
     Debug.Assert(n < sample.Num1D[offsets.ComponentOffset]);
     UPos0 = sample.TwoD[offsets.PosOffset][2 * n];
     UPos1 = sample.TwoD[offsets.PosOffset][2 * n + 1];
     UComponent = sample.OneD[offsets.ComponentOffset][n];
     Debug.Assert(UPos0 >= 0.0f && UPos0 < 1.0f);
     Debug.Assert(UPos1 >= 0.0f && UPos1 < 1.0f);
     Debug.Assert(UComponent >= 0.0f && UComponent < 1.0f);
 }
Exemple #6
0
 public Sample[] Duplicate(int count)
 {
     var ret = new Sample[count];
     for (var i = 0; i < count; ++i)
     {
         ret[i] = new Sample
         {
             Num1D = Num1D.Select(x => x).ToList(),
             Num2D = Num2D.Select(x => x).ToList()
         };
         ret[i].AllocateSampleMemory();
     }
     return ret;
 }
        public override int GetMoreSamples(Sample[] samples, Random rng)
        {
            if (_yPos == YEnd) return 0;
            int nSamples = _xPixelSamples * _yPixelSamples;
            // Generate stratified camera samples for _(xPos, yPos)_

            // Generate initial stratified samples into _sampleBuf_ memory
            IList<float> imageSamples = new ArraySegment<float>(_sampleBuffer, 0, 2 * nSamples);
            IList<float> lensSamples = new ArraySegment<float>(_sampleBuffer, 2 * nSamples, 2 * nSamples);
            IList<float> timeSamples = new ArraySegment<float>(_sampleBuffer, 4 * nSamples, nSamples);
            SamplingUtilities.StratifiedSample2D(imageSamples, _xPixelSamples, _yPixelSamples, rng, _jitter);
            SamplingUtilities.StratifiedSample2D(lensSamples, _xPixelSamples, _yPixelSamples, rng, _jitter);
            SamplingUtilities.StratifiedSample1D(timeSamples, _xPixelSamples * _yPixelSamples, rng, _jitter);

            // Shift stratified image samples to pixel coordinates
            for (int o = 0; o < 2 * _xPixelSamples * _yPixelSamples; o += 2)
            {
                imageSamples[o] += _xPos;
                imageSamples[o + 1] += _yPos;
            }

            // Decorrelate sample dimensions
            SamplingUtilities.Shuffle(lensSamples, _xPixelSamples * _yPixelSamples, 2, rng);
            SamplingUtilities.Shuffle(timeSamples, _xPixelSamples * _yPixelSamples, 1, rng);

            // Initialize stratified _samples_ with sample values
            for (int i = 0; i < nSamples; ++i)
            {
                samples[i].ImageX = imageSamples[2 * i];
                samples[i].ImageY = imageSamples[2 * i + 1];
                samples[i].LensU = lensSamples[2 * i];
                samples[i].LensV = lensSamples[2 * i + 1];
                samples[i].Time = MathUtility.Lerp(timeSamples[i], ShutterOpen, ShutterClose);
                // Generate stratified samples for integrators
                for (var j = 0; j < samples[i].Num1D.Count; ++j)
                    MonteCarloUtilities.LatinHypercube(samples[i].OneD[j], samples[i].Num1D[j], 1, rng);
                for (var j = 0; j < samples[i].Num2D.Count; ++j)
                    MonteCarloUtilities.LatinHypercube(samples[i].TwoD[j], samples[i].Num2D[j], 2, rng);
            }

            // Advance to next pixel for stratified sampling
            if (++_xPos == XEnd)
            {
                _xPos = XStart;
                ++_yPos;
            }
            return nSamples;
        }
        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;
        }
        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;
        }
 public abstract Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray,
     Sample sample, Random rng, out Spectrum transmittance);
Exemple #11
0
 public virtual bool ReportResults(Sample[] samples, RayDifferential[] rays,
     Spectrum[] ls, Intersection[] intersections, int count)
 {
     return true;
 }
Exemple #12
0
 public abstract int GetMoreSamples(Sample[] samples, Random rng);
 public LightSampleOffsets(int numSamples, Sample sample)
 {
     NumSamples = numSamples;
     ComponentOffset = sample.Add1D(numSamples);
     PosOffset = sample.Add2D(numSamples);
 }
Exemple #14
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);
 }
Exemple #15
0
 public abstract Spectrum Transmittance(Scene scene, RayDifferential ray, Sample sample,
     Random rng);
Exemple #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;
 }
Exemple #17
0
 public abstract Spectrum Li(Scene scene, RayDifferential ray, Sample sample, Random rng,
     ref Intersection intersection, out Spectrum t);
Exemple #18
0
 public virtual void RequestSamples(Sampler sampler, Sample sample, Scene scene)
 {
     
 }
 public abstract Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray,
     Intersection intersection, Sample sample, Random rng);
 public override Spectrum Transmittance(Scene scene, Renderer renderer, RayDifferential ray, Sample sample, Random rng)
 {
     // TODO
     return new Spectrum(1.0f);
 }
 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();
 }
Exemple #22
0
 public override Spectrum Transmittance(Scene scene, RayDifferential ray, Sample sample, Random rng)
 {
     return _volumeIntegrator.Transmittance(scene, this, ray, sample, rng);
 }