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; }
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; }
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); }
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 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); }
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; } }
public abstract Spectrum Transmittance(Scene scene, RayDifferential ray, Sample sample, Random rng);
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); }
public abstract Spectrum Li(Scene scene, RayDifferential ray, Sample sample, Random rng, ref Intersection intersection, out Spectrum t);
public virtual Spectrum Le(RayDifferential r) { return Spectrum.CreateBlack(); }
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; }
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(); }
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); }
public override Spectrum Transmittance(Scene scene, RayDifferential ray, Sample sample, Random rng) { return _volumeIntegrator.Transmittance(scene, this, ray, sample, rng); }
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; }
public virtual bool ReportResults(Sample[] samples, RayDifferential[] rays, Spectrum[] ls, Intersection[] intersections, int count) { return true; }
public Bssrdf GetBssrdf(RayDifferential ray) { _dg.ComputeDifferentials(ray); return _primitive.GetBssrdf(_dg, ObjectToWorld); }
public override Spectrum Transmittance(Scene scene, Renderer renderer, RayDifferential ray, Sample sample, Random rng) { // TODO return new Spectrum(1.0f); }
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; }
public abstract Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray, Sample sample, Random rng, out Spectrum transmittance);
public abstract Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray, Intersection intersection, Sample sample, Random rng);