private bool DoIntersection(Ray r, out float phi, out float dist2, out Point phit, out float thit) { phi = dist2 = thit = 0; phit = Point.Zero; // Transform _Ray_ to object space Ray ray = WorldToObject.TransformRay(r); // Compute plane intersection for disk if (Math.Abs(ray.Direction.Z) < 1e-7) return false; thit = (_height - ray.Origin.Z) / ray.Direction.Z; if (thit < ray.MinT || thit > ray.MaxT) return false; // See if hit point is inside disk radii and $\phimax$ phit = ray.Evaluate(thit); dist2 = phit.X * phit.X + phit.Y * phit.Y; if (dist2 > _radius * _radius || dist2 < _innerRadius * _innerRadius) return false; // Test disk $\phi$ value against $\phimax$ phi = MathUtility.Atan2(phit.Y, phit.X); if (phi < 0) phi += 2.0f * MathUtility.Pi; if (phi > _phiMax) return false; return true; }
public override bool TryIntersect(Ray r, ref Intersection intersection) { Transform w2p; _worldToPrimitive.Interpolate(r.Time, out w2p); Ray ray = w2p.TransformRay(r); if (!_primitive.TryIntersect(ray, ref intersection)) return false; r.MaxT = ray.MaxT; if (!w2p.IsIdentity()) { // Compute world-to-object transformation for instance intersection.WorldToObject = intersection.WorldToObject * w2p; intersection.ObjectToWorld = Transform.Invert(intersection.WorldToObject); // Transform instance's differential geometry to world space Transform primitiveToWorld = Transform.Invert(w2p); var dg = intersection.DifferentialGeometry; dg.Point = primitiveToWorld.TransformPoint(ref dg.Point); dg.Normal = Normal.Normalize(primitiveToWorld.TransformNormal(ref dg.Normal)); dg.DpDu = primitiveToWorld.TransformVector(ref dg.DpDu); dg.DpDv = primitiveToWorld.TransformVector(ref dg.DpDv); dg.DnDu = primitiveToWorld.TransformNormal(ref dg.DnDu); dg.DnDv = primitiveToWorld.TransformNormal(ref dg.DnDv); } return true; }
public override float GenerateRay(CameraSample sample, out Ray ray) { // Generate raster and camera samples Point Pras = new Point(sample.ImageX, sample.ImageY, 0); Point Pcamera = RasterToCamera.TransformPoint(ref Pras); ray = new Ray(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); } ray.Time = sample.Time; ray = CameraToWorld.TransformRay(ray); return 1.0f; }
public override Spectrum SampleL(Scene scene, LightSample ls, float u1, float u2, float time, out Ray ray, out Normal ns, out float pdf) { ray = new Ray(_lightPosition, MonteCarloUtilities.UniformSampleSphere(ls.UPos0, ls.UPos1), 0.0f, float.PositiveInfinity, time); ns = (Normal) ray.Direction; pdf = MonteCarloUtilities.UniformSpherePdf(); return _intensity; }
public override bool TryIntersect(Ray r, out float tHit, out float rayEpsilon, out DifferentialGeometry dg) { tHit = float.NegativeInfinity; rayEpsilon = 0.0f; dg = null; float phi; Point phit; float thit; if (!DoIntersection(r, out phi, out phit, out thit)) return false; // Find parametric representation of cylinder hit float u = phi / _phiMax; float v = (phit.Z - _zMin) / (_zMax - _zMin); // Compute cylinder $\dpdu$ and $\dpdv$ var dpdu = new Vector(-_phiMax * phit.Y, _phiMax * phit.X, 0); var dpdv = new Vector(0, 0, _zMax - _zMin); // Compute cylinder $\dndu$ and $\dndv$ Vector d2Pduu = -_phiMax * _phiMax * new Vector(phit.X, phit.Y, 0); Vector d2Pduv = Vector.Zero, d2Pdvv = Vector.Zero; // Compute coefficients for fundamental forms float E = Vector.Dot(dpdu, dpdu); float F = Vector.Dot(dpdu, dpdv); float G = Vector.Dot(dpdv, dpdv); Vector N = Vector.Normalize(Vector.Cross(dpdu, dpdv)); float e = Vector.Dot(N, d2Pduu); float f = Vector.Dot(N, d2Pduv); float g = Vector.Dot(N, d2Pdvv); // Compute $\dndu$ and $\dndv$ from fundamental form coefficients float invEGF2 = 1.0f / (E * G - F * F); var dndu = (Normal) ((f * F - e * G) * invEGF2 * dpdu + (e * F - f * E) * invEGF2 * dpdv); var dndv = (Normal) ((g * F - f * G) * invEGF2 * dpdu + (f * F - g * E) * invEGF2 * dpdv); // Initialize _DifferentialGeometry_ from parametric information var o2w = ObjectToWorld; dg = new DifferentialGeometry(o2w.TransformPoint(ref phit), o2w.TransformVector(ref dpdu), o2w.TransformVector(ref dpdv), o2w.TransformNormal(ref dndu), o2w.TransformNormal(ref dndv), u, v, this); // Update _tHit_ for quadric intersection tHit = thit; // Compute _rayEpsilon_ for quadric intersection rayEpsilon = 5e-4f * tHit; return true; }
public override bool TryIntersect(Ray ray, ref Intersection intersection) { float thit, rayEpsilon; DifferentialGeometry dg; if (!_shape.TryIntersect(ray, out thit, out rayEpsilon, out dg)) return false; intersection = new Intersection(dg, this, _shape.ObjectToWorld, _shape.WorldToObject, rayEpsilon); ray.MaxT = thit; return true; }
public bool TryIntersect(Ray ray, ref Intersection intersection) { RefineIfNeeded(); // Loop over primitives in voxel and find intersections bool hitSomething = false; for (var i = 0; i < _primitives.Count; ++i) { var prim = _primitives[i]; if (prim.TryIntersect(ray, ref intersection)) hitSomething = true; } return hitSomething; }
public virtual float Pdf(Point p, Vector wi) { // Intersect sample ray with area light geometry var ray = new Ray(p, wi, 1e-3f); ray.Depth = -1; // temporary hack to ignore alpha mask float thit, rayEpsilon; DifferentialGeometry dgLight; if (!TryIntersect(ray, out thit, out rayEpsilon, out dgLight)) return 0.0f; // Convert light sample weight to solid angle measure float pdf = Point.DistanceSquared(p, ray.Evaluate(thit)) / (Normal.AbsDot(dgLight.Normal, -wi) * Area); if (float.IsInfinity(pdf)) pdf = 0.0f; return pdf; }
public override Spectrum SampleL(Scene scene, LightSample ls, float u1, float u2, float time, out Ray ray, out Normal ns, out float pdf) { // Choose point on disk oriented toward infinite light direction Point worldCenter; float worldRadius; scene.WorldBound.BoundingSphere(out worldCenter, out worldRadius); Vector v1, v2; Vector.CoordinateSystem(_direction, out v1, out v2); float d1, d2; MonteCarloUtilities.ConcentricSampleDisk(ls.UPos0, ls.UPos1, out d1, out d2); Point Pdisk = worldCenter + worldRadius * (d1 * v1 + d2 * v2); // Set ray origin and direction for infinite light ray ray = new Ray(Pdisk + worldRadius * _direction, -_direction, 0.0f, float.PositiveInfinity, time); ns = (Normal) ray.Direction; pdf = 1.0f / (MathUtility.Pi * worldRadius * worldRadius); return _radiance; }
public override bool TryIntersect(Ray r, out float tHit, out float rayEpsilon, out DifferentialGeometry dg) { tHit = float.NegativeInfinity; rayEpsilon = 0.0f; dg = null; float phi, dist2, thit; Point phit; if (!DoIntersection(r, out phi, out dist2, out phit, out thit)) return false; // Find parametric representation of disk hit float u = phi / _phiMax; float oneMinusV = ((MathUtility.Sqrt(dist2) - _innerRadius) / (_radius - _innerRadius)); float invOneMinusV = (oneMinusV > 0.0f) ? (1.0f / oneMinusV) : 0.0f; float v = 1.0f - oneMinusV; var dpdu = new Vector(-_phiMax * phit.Y, _phiMax * phit.X, 0.0f); var dpdv = new Vector(-phit.X * invOneMinusV, -phit.Y * invOneMinusV, 0.0f); dpdu *= _phiMax * MathUtility.InvTwoPi; dpdv *= (_radius - _innerRadius) / _radius; Normal dndu = Normal.Zero, dndv = Normal.Zero; // Initialize _DifferentialGeometry_ from parametric information var o2w = ObjectToWorld; dg = new DifferentialGeometry(o2w.TransformPoint(ref phit), o2w.TransformVector(ref dpdu), o2w.TransformVector(ref dpdv), o2w.TransformNormal(ref dndu), o2w.TransformNormal(ref dndv), u, v, this); // Update _tHit_ for quadric intersection tHit = thit; // Compute _rayEpsilon_ for quadric intersection rayEpsilon = 5e-4f * tHit; return true; }
private bool DoIntersection(Ray r, out float phi, out Point phit, out float thit) { phi = 0.0f; phit = new Point(); thit = 0.0f; // Transform _Ray_ to object space Ray ray = WorldToObject.TransformRay(r); // Compute quadratic cylinder coefficients float A = ray.Direction.X * ray.Direction.X + ray.Direction.Y * ray.Direction.Y; float B = 2 * (ray.Direction.X * ray.Origin.X + ray.Direction.Y * ray.Origin.Y); float C = ray.Origin.X * ray.Origin.X + ray.Origin.Y * ray.Origin.Y - _radius * _radius; // Solve quadratic equation for _t_ values float t0, t1; if (!MathUtility.TryQuadratic(A, B, C, out t0, out t1)) return false; // Compute intersection distance along ray if (t0 > ray.MaxT || t1 < ray.MinT) return false; thit = t0; if (t0 < ray.MinT) { thit = t1; if (thit > ray.MaxT) return false; } // Compute cylinder hit point and $\phi$ phit = ray.Evaluate(thit); phi = MathUtility.Atan2(phit.Y, phit.X); if (phi < 0.0) phi += 2.0f * MathUtility.Pi; // Test cylinder intersection against clipping parameters if (phit.Z < _zMin || phit.Z > _zMax || phi > _phiMax) { if (thit == t1) return false; thit = t1; if (t1 > ray.MaxT) return false; // Compute cylinder hit point and $\phi$ phit = ray.Evaluate(thit); phi = MathUtility.Atan2(phit.Y, phit.X); if (phi < 0.0f) phi += 2.0f * MathUtility.Pi; if (phit.Z < _zMin || phit.Z > _zMax || phi > _phiMax) return false; } return true; }
public override bool Intersects(Ray ray) { float phi; Point phit; float thit; return DoIntersection(ray, out phi, out phit, out thit); }
public bool TryIntersect(Ray ray, out float t0) { float t1; return TryIntersect(ray, out t0, out t1); }
public bool Intersects(Ray ray) { return _aggregate.Intersects(ray); }
public override Spectrum SampleL(Scene scene, LightSample ls, float u1, float u2, float time, out Ray ray, out Normal ns, out float pdf) { throw new System.NotImplementedException(); }
private void DoIntersect(Ray ray, Func<GridVoxel, bool> callback) { // Check ray against overall grid bounds float rayT; if (_bounds.Inside(ray.Evaluate(ray.MinT))) rayT = ray.MinT; else if (!_bounds.TryIntersect(ray, out rayT)) return; Point gridIntersect = ray.Evaluate(rayT); // Set up 3D DDA for ray float[] NextCrossingT = new float[3], DeltaT = new float[3]; int[] Step = new int[3], Out = new int[3], Pos = new int[3]; for (int axis = 0; axis < 3; ++axis) { // Compute current voxel for axis Pos[axis] = PosToVoxel(ref gridIntersect, axis); if (ray.Direction[axis] >= 0) { // Handle ray with positive direction for voxel stepping NextCrossingT[axis] = rayT + (VoxelToPos(Pos[axis] + 1, axis) - gridIntersect[axis]) / ray.Direction[axis]; DeltaT[axis] = _width[axis] / ray.Direction[axis]; Step[axis] = 1; Out[axis] = _numVoxels[axis]; } else { // Handle ray with negative direction for voxel stepping NextCrossingT[axis] = rayT + (VoxelToPos(Pos[axis], axis) - gridIntersect[axis]) / ray.Direction[axis]; DeltaT[axis] = -_width[axis] / ray.Direction[axis]; Step[axis] = -1; Out[axis] = -1; } } // Walk ray through voxel grid while (true) { // Check for intersection in current voxel and advance to next var voxel = _voxels[Offset(Pos[0], Pos[1], Pos[2])]; if (voxel != null) if (callback(voxel)) break; // Advance to next voxel // Find _stepAxis_ for stepping to next voxel int bits = (((NextCrossingT[0] < NextCrossingT[1]) ? 1 : 0) << 2) + (((NextCrossingT[0] < NextCrossingT[2]) ? 1 : 0) << 1) + (((NextCrossingT[1] < NextCrossingT[2]) ? 1 : 0)); int stepAxis = CmpToAxis[bits]; if (ray.MaxT < NextCrossingT[stepAxis]) break; Pos[stepAxis] += Step[stepAxis]; if (Pos[stepAxis] == Out[stepAxis]) break; NextCrossingT[stepAxis] += DeltaT[stepAxis]; } }
public abstract bool Intersects(Ray ray);
public VisibilityTester(Point p, float eps, Vector w, float time) { Ray = new Ray(p, w, eps, float.PositiveInfinity, time); }
public VisibilityTester(Point p1, float eps1, Point p2, float eps2, float time) { float dist = Point.Distance(p1, p2); Ray = new Ray(p1, (p2 - p1) / dist, eps1, dist * (1.0f - eps2), time); }
public abstract Spectrum SampleL(Scene scene, LightSample ls, float u1, float u2, float time, out Ray ray, out Normal ns, out float pdf);
public bool Intersects(Ray ray) { float t0, t1; return TryIntersect(ray, out t0, out t1); }
public override bool Intersects(Ray ray) { return _primitive.Intersects(_worldToPrimitive.TransformRay(ray)); }
public override bool Intersects(Ray ray) { var result = false; DoIntersect(ray, voxel => result = voxel.Intersects(ray)); return result; }
public override bool Intersects(Ray ray) { return _shape.Intersects(ray); }
public override bool TryIntersect(Ray ray, ref Intersection intersection) { // Walk ray through voxel grid bool hitSomething = false; Intersection tempIntersection = null; DoIntersect(ray, voxel => { hitSomething |= voxel.TryIntersect(ray, ref tempIntersection); return false; }); if (hitSomething) intersection = tempIntersection; return hitSomething; }
public abstract float GenerateRay(CameraSample sample, out Ray ray);
public bool TryIntersect(Ray ray, ref Intersection intersection) { return _aggregate.TryIntersect(ray, ref intersection); }
public abstract bool TryIntersect(Ray ray, ref Intersection intersection);
public Ray TransformRay(Ray r) { Ray tr; if (!_actuallyAnimated || r.Time <= _startTime) tr = _startTransform.TransformRay(r); else if (r.Time >= _endTime) tr = _endTransform.TransformRay(r); else { Transform t; Interpolate(r.Time, out t); tr = t.TransformRay(r); } tr.Time = r.Time; return tr; }
public bool TryIntersect(Ray ray, out float t0, out float t1) { t0 = ray.MinT; t1 = ray.MaxT; for (int i = 0; i < 3; ++i) { // Update interval for _i_th bounding box slab float invRayDir = 1.0f / ray.Direction[i]; float tNear = (Min[i] - ray.Origin[i]) * invRayDir; float tFar = (Max[i] - ray.Origin[i]) * invRayDir; // Update parametric interval from slab intersection $t$s if (tNear > tFar) MathUtility.Swap(ref tNear, ref tFar); t0 = tNear > t0 ? tNear : t0; t1 = tFar < t1 ? tFar : t1; if (t0 > t1) return false; } return true; }