public static Spectrum SpecularReflect(RayDifferential ray, BSDF bsdf, Intersection isect, IRenderer renderer, Scene scene, Sample sample) { Vector wo = -ray.Direction, wi = new Vector (); double pdf = 0.0; Point p = bsdf.dgShading.p; Normal n = bsdf.dgShading.n; Spectrum f = bsdf.SampleF (wo, ref wi, new BSDFSample (), ref pdf, BxDFType.BSDF_REFLECTION | BxDFType.BSDF_SPECULAR); Spectrum L = new Spectrum (); if (pdf > 0.0 && !f.IsBlack && Util.AbsDot (wi, n) != 0.0) { RayDifferential rd = new RayDifferential (p, wi, ray, isect.RayEpsilon); if (ray.HasDifferentials) { rd.HasDifferentials = true; rd.RxOrigin = p + isect.dg.dpdx; rd.RyOrigin = p + isect.dg.dpdy; 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.Direction - wo; double dDNdx = (dwodx ^ n) + (wo ^ dndx); double dDNdy = (dwody ^ n) + (wo ^ dndy); rd.RxDirection = wi - dwodx + 2 * new Vector ((wo ^ n) * dndx + dDNdx * n); rd.RyDirection = wi - dwody + 2 * new Vector ((wo ^ n) * dndy + dDNdy * n); } Spectrum Li = renderer.Li (scene, rd, sample); L = f * Li * Util.AbsDot (wi, n) / pdf; } return L; }
public void Run() { ISampler sampler = MainSampler.GetSubSampler (TaskNumber, TaskCount); if (sampler == null) { return; } int maxSamples = sampler.MaximumSampleCount; Sample[] samples = OrigSample.Duplicate (maxSamples); RayDifferential[] rays = new RayDifferential[maxSamples]; Spectrum[] Ls = new Spectrum[maxSamples]; Spectrum[] Ts = new Spectrum[maxSamples]; Intersection[] isects = new Intersection[maxSamples]; for (int i = 0; i < maxSamples; ++i) { samples[i] = new Sample (); rays[i] = new RayDifferential (); Ls[i] = new Spectrum (); Ts[i] = new Spectrum (); isects[i] = new Intersection (); } int sampleCount; while ((sampleCount = sampler.GetMoreSamples (samples)) > 0) { for (int i = 0; i < sampleCount; ++i) { double rayWeight = Camera.GenerateRayDifferential (samples[i], ref rays[i]); rays[i].ScaleDifferentials (1.0 / Math.Sqrt (sampler.SamplesPerPixel)); if (rayWeight > 0.0) Ls[i] = rayWeight * Renderer.Li (Scene, rays[i], samples[i], ref isects[i], ref Ts[i]); else { Ls[i] = new Spectrum (); Ts[i] = new Spectrum (1.0); } // WARNINGS } 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.xPixelStart, sampler.yPixelStart, sampler.xPixelEnd + 1, sampler.yPixelEnd + 1); Reporter.Update (); }
public override bool Intersect(Ray ray, ref Intersection isect) { double thit = 0.0, rayEpsilon = 0.0; if (!Shape.Intersect (ray, ref thit, ref rayEpsilon, ref isect.dg)) return false; isect.Primitive = this; isect.WorldToObject = Shape.WorldToObject; isect.ObjectToWorld = Shape.ObjectToWorld; isect.ShapeID = Shape.ShapeID; isect.PrimitiveID = PrimitiveID; isect.RayEpsilon = rayEpsilon; ray.MaxT = thit; return true; }
public static Spectrum SpecularTransmit(RayDifferential ray, BSDF bsdf, Intersection isect, IRenderer renderer, Scene scene, Sample sample) { Vector wo = -ray.Direction, wi = new Vector (); double pdf = 0.0; Point p = bsdf.dgShading.p; Normal n = bsdf.dgShading.n; Spectrum f = bsdf.SampleF (wo, ref wi, new BSDFSample (), ref pdf, BxDFType.BSDF_TRANSMISSION | BxDFType.BSDF_SPECULAR); Spectrum L = new Spectrum (); if (pdf > 0.0 && !f.IsBlack && Util.AbsDot (wi, n) != 0.0) { RayDifferential rd = new RayDifferential (p, wi, ray, isect.RayEpsilon); if (ray.HasDifferentials) { rd.HasDifferentials = true; rd.RxOrigin = p + isect.dg.dpdx; rd.RyOrigin = p + isect.dg.dpdy; double eta = bsdf.Eta; Vector w = -wo; if ((wo ^ n) < 0.0) eta = 1.0 / 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; double dDNdx = (dwodx ^ n) + (wo ^ dndx); double dDNdy = (dwody ^ n) + (wo ^ dndy); double mu = eta * (w ^ n) - (wi ^ n); double dmudx = (eta - (eta * eta * (w ^ n)) / (wi ^ n)) * dDNdx; double dmudy = (eta - (eta * eta * (w ^ n)) / (wi ^ n)) * dDNdy; rd.RxDirection = wi + eta * dwodx - new Vector (mu * dndx + dmudx * n); rd.RyDirection = wi + eta * dwody - new Vector (mu * dndy + dmudy * n); } Spectrum Li = renderer.Li (scene, rd, sample); L = f * Li * Util.AbsDot (wi, n) / pdf; } return L; }
public abstract Spectrum Li(Scene scene, IRenderer renderer, RayDifferential ray, Intersection isect, Sample sample);
public override bool Intersect(Ray ray, ref Intersection intersection) { double rayT = 0.0, t = 0.0; if (Bounds.Inside (ray.Apply (ray.MinT))) rayT = ray.MinT; else if (!Bounds.IntersectP (ray, out rayT, out t)) return false; Point gridIntersect = ray.Apply (rayT); double[] nextCrossing = new double[3]; double[] delta = new double[3]; int[] Step = new int[3]; int[] Out = new int[3]; int[] Pos = new int[3]; for (int axis = 0; axis < 3; ++axis) { Pos[axis] = PositionToVoxel (gridIntersect, axis); if (ray.Direction[axis] >= 0) { nextCrossing[axis] = rayT + (VoxelToPos (Pos[axis] + 1, axis) - gridIntersect[axis]) / ray.Direction[axis]; delta[axis] = Width[axis] / ray.Direction[axis]; Step[axis] = 1; Out[axis] = nVoxels[axis]; } else { nextCrossing[axis] = rayT + (VoxelToPos(Pos[axis], axis) - gridIntersect[axis]) / ray.Direction[axis]; delta[axis] = -Width[axis] / ray.Direction[axis]; Step[axis] = -1; Out[axis] = -1; } } bool hitSomething = false; while (true) { Voxel voxel = Voxels[Offset (Pos[0], Pos[1], Pos[2])]; if (voxel != null) { hitSomething |= voxel.Intersect (ray, ref intersection); } int bits = (((nextCrossing[0] < nextCrossing[1]) ? 1 : 0) << 2) + (((nextCrossing[0] < nextCrossing[2]) ? 1 : 0) << 1) + (((nextCrossing[1] < nextCrossing[2]) ? 1 : 0)); int[] cmpTpAxis = new int[] { 2, 1, 2, 1, 2, 2, 0, 0 }; int stepAxis = cmpTpAxis[bits]; if (ray.MaxT < nextCrossing[stepAxis]) { break; } Pos[stepAxis] += Step[stepAxis]; if (Pos[stepAxis] == Out[stepAxis]) break; nextCrossing[stepAxis] += delta[stepAxis]; } return hitSomething; }
public Spectrum Li(Scene scene, RayDifferential ray, Sample sample, ref Intersection isect) { Spectrum T = new Spectrum (); return Li (scene, ray, sample, ref isect, ref T); }
public abstract Spectrum Li(Scene scene, RayDifferential ray, Sample sample, ref Intersection isect, ref Spectrum T);
/// <summary> /// Checks if the given ray intersects the primitive. /// </summary> /// <param name="ray"> /// The ray to test for /// </param> /// <param name="intersection"> /// A pointer to an Intersection structure that'll hold /// the intersection information. /// </param> /// <returns> /// True if the ray intersects the primitive. False otherwise. /// </returns> public override bool Intersect(Ray ray, ref Intersection intersection) { int index = 0; double tMin = 0.0, tMax = 0.0; if (!_bounds.IntersectP (ray, out tMin, out tMax)) { return false; } Vector inverseDirection = new Vector (1.0 / ray.Direction.x, 1.0 / ray.Direction.y, 1.0 / ray.Direction.z); int todoPosition = 0; bool hit = false; KdToDo[] todo = ToDoPool.Get (); while (index >= 0 && index < _nodes.Length) { if (ray.MaxT < tMin) break; if (!_nodes[index].IsLeaf) { int axis = _nodes[index].SplitAxis; double tPlane = (_nodes[index].Split - ray.Origin[axis]) * inverseDirection[axis]; int firstIndex, secondIndex; bool belowFirst = (ray.Origin[axis] < _nodes[index].Split) || (ray.Origin[axis] == _nodes[index].Split && ray.Direction[axis] >= 0); if (belowFirst) { firstIndex = index + 1; secondIndex = _nodes[index].AboveChild; } else { firstIndex = _nodes[index].AboveChild; secondIndex = index + 1; } if (tPlane > tMax || tPlane <= 0) { index = firstIndex; } else if (tPlane < tMin) { index = secondIndex; } else { todo[todoPosition].tMax = tMax; todo[todoPosition].tMin = tPlane; todo[todoPosition].Index = secondIndex; ++todoPosition; index = firstIndex; tMax = tPlane; } } else { if (_nodes[index].NumberOfPrimitives == 1) { IPrimitive prim = _primitives[_nodes[index].OnePrimitive]; if (prim.Intersect (ray, ref intersection)) { hit = true; } } else { for (int i = 0; i < _nodes[index].NumberOfPrimitives; ++i) { IPrimitive prim = _primitives[_nodes[index].Primitives[i]]; if (prim.Intersect (ray, ref intersection)) { hit = true; } } } if (todoPosition > 0) { --todoPosition; tMin = todo[todoPosition].tMin; tMax = todo[todoPosition].tMax; index = todo[todoPosition].Index; } else { break; } } } ToDoPool.Free (todo); return hit; }
public abstract bool Intersect(Ray ray, ref Intersection isect);
public bool Intersect(Ray ray, ref Intersection isect) { return Aggregate.Intersect (ray, ref isect); }
public virtual bool ReportResults(Sample[] samples, RayDifferential[] rays, Spectrum[] Ls, Intersection[] isects, int count) { return true; }