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; }
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 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 Point Sample(Point p, float u1, float u2, out Normal ns) { // Compute coordinate system for sphere sampling Point Pcenter = ObjectToWorld.TransformPoint(Point.Zero); Vector wc = Vector.Normalize(Pcenter - p); Vector wcX, wcY; Vector.CoordinateSystem(wc, out wcX, out wcY); // Sample uniformly on sphere if $\pt{}$ is inside it if (Point.DistanceSquared(p, Pcenter) - _radius * _radius < 1e-4f) return Sample(u1, u2, out ns); // Sample sphere uniformly inside subtended cone float sinThetaMax2 = _radius * _radius / Point.DistanceSquared(p, Pcenter); float cosThetaMax = MathUtility.Sqrt(Math.Max(0.0f, 1.0f - sinThetaMax2)); DifferentialGeometry dgSphere; float thit, rayEpsilon; Point ps; Ray r = new Ray(p, MonteCarloUtilities.UniformSampleCone(u1, u2, cosThetaMax, ref wcX, ref wcY, ref wc), 1e-3f); if (!TryIntersect(r, out thit, out rayEpsilon, out dgSphere)) thit = Vector.Dot(Pcenter - p, Vector.Normalize(r.Direction)); ps = r.Evaluate(thit); ns = (Normal) Vector.Normalize(ps - Pcenter); if (ReverseOrientation) ns *= -1.0f; return ps; }