Example #1
0
        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;
        }
Example #3
0
        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;
        }
Example #4
0
 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;
 }
Example #5
0
        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;
        }
Example #6
0
 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;
 }
Example #7
0
        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;
        }
Example #8
0
        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;
        }
Example #9
0
        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;
        }
Example #10
0
        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;
        }
Example #11
0
        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;
        }
Example #12
0
 public override bool Intersects(Ray ray)
 {
     float phi;
     Point phit;
     float thit;
     return DoIntersection(ray, out phi, out phit, out thit);
 }
Example #13
0
 public bool TryIntersect(Ray ray, out float t0)
 {
     float t1;
     return TryIntersect(ray, out t0, out t1);
 }
Example #14
0
 public bool Intersects(Ray ray)
 {
     return _aggregate.Intersects(ray);
 }
Example #15
0
 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();
 }
Example #16
0
        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];
            }
        }
Example #17
0
 public abstract bool Intersects(Ray ray);
Example #18
0
 public VisibilityTester(Point p, float eps, Vector w, float time)
 {
     Ray = new Ray(p, w, eps, float.PositiveInfinity, time);
 }
Example #19
0
 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);
 }
Example #20
0
 public abstract Spectrum SampleL(Scene scene, LightSample ls, float u1, float u2,
     float time, out Ray ray, out Normal ns, out float pdf);
Example #21
0
 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));
 }
Example #23
0
 public override bool Intersects(Ray ray)
 {
     var result = false;
     DoIntersect(ray, voxel => result = voxel.Intersects(ray));
     return result;
 }
Example #24
0
 public override bool Intersects(Ray ray)
 {
     return _shape.Intersects(ray);
 }
Example #25
0
 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;
 }
Example #26
0
 public abstract float GenerateRay(CameraSample sample, out Ray ray);
Example #27
0
 public bool TryIntersect(Ray ray, ref Intersection intersection)
 {
     return _aggregate.TryIntersect(ray, ref intersection);
 }
Example #28
0
 public abstract bool TryIntersect(Ray ray, ref Intersection intersection);
Example #29
0
 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;
 }
Example #30
0
        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;
        }