public RayInfo(RayInfo vray) { this.Org = vray.Org; this.Dir = vray.Dir; InvDir = 1f / vray.Dir; this.MinT = vray.MinT; this.MaxT = vray.MaxT; }
public override Spectrum tau(RayInfo r, float stepSize, float offset) { float t0, t1; float length = r.Dir.Length; if (length == 0f) return RgbSpectrum.ZeroSpectrum(); RayInfo rn = new RayInfo(r.Org, r.Dir / length, r.MinT * length, r.MaxT * length); if (!IntersectP(rn, out t0, out t1)) return RgbSpectrum.ZeroSpectrum(); Spectrum tau = new RgbSpectrum(); t0 += offset * stepSize; while (t0 < t1) { var pt = rn.Point(t0); var d = -rn.Dir; tau += sigma_t(ref pt, ref d, 1.0f); t0 += stepSize; } return tau * stepSize; }
public RgbSpectrum SamplePhoton(SceneGeometryInfo scene, float u0, float u1, float u2, float u3, float u4, out float pdf, out RayInfo ray) { // Choose two points p1 and p2 on scene bounding sphere var worldCenter = scene.BoundingSphereCenter; var worldRadius = scene.BoundingSphereRadius * 1.01f; var p1 = worldCenter + worldRadius * MC.UniformSampleSphere(u0, u1); var p2 = worldCenter + worldRadius * MC.UniformSampleSphere(u2, u3); // Construct ray between p1 and p2 ray = new RayInfo(p1, (p2 - p1).Normalize(), 1e-4f, 1e4f); // Compute InfiniteAreaLight ray weight Vector toCenter = (worldCenter - p1).Normalize(); var rayDir = ray.Dir; float costheta = MathLab.AbsDot(ref toCenter, ref rayDir); pdf = costheta / (4f * MathLab.M_PI * MathLab.M_PI * worldRadius * worldRadius); return Le(ray.Dir); }
public bool Intersect(ref RayInfo ray) { return ShadowIntersectBVH(ref ray); //return IntersectNode(RootNode, ray); }
public bool Intersect(ref RayInfo ray, out RayHit intersection) { intersection = new RayHit(); //return IntersectLBVH(ref ray, ref intersection); return IntersectBVH(ref ray, ref intersection); //return IntersectNode(RootNode, ray, out intersection); }
private RgbSpectrum ShadeBackground(RayInfo ray) { if (EnvironmentMap == null) { return RgbSpectrum.ZeroSpectrum(); } return EnvironmentMap.Le(-ray.Dir); }
private void Intersect(ref RayInfo rayInfo, ref RayHit rayHit) { //accel.Intersect(ref rayInfo, out rayHit); }
public RgbSpectrum Sample(ref Point point, ref Normal n, float u0, float u1, float u2, out RayInfo ray, out float pdf) { var dir = (Position - point); var l2 = dir.Length; dir.Normalize(); pdf = MC.UniformSpherePdf(); ray = new RayInfo(point, dir, 1e-4f, l2 - 1e-4f); return Power / l2; }
public RgbSpectrum SamplePhoton(SceneGeometryInfo scene, float u0, float u1, float u2, float u3, float u4, out float pdf, out RayInfo ray) { Vector dir = MC.UniformSampleSphere(u0, u1); ray = new RayInfo(Position+dir*Radius, dir, 1e-4f, 1e4f); pdf = MathLab.INV4PI; return (Power * Radius * MathLab.M_PI * 4f); }
public RgbSpectrum Sample(ref Point point, ref Normal n, float u0, float u1, float u2, out RayInfo ray, out float pdf) { var samplePoint = new Point(); float b0, b1, b2; int tries = 0; int maxTries = 0; startTry: var tri = SampleTriangle(); tri.Sample(ref mesh.scene.Vertices, u2, u1, out samplePoint, out b0, out b1, out b2); var TriangleNormal =NormalModifier * tri.ComputeNormal(ref mesh.scene.Vertices); var area = tri.AreaV(ref mesh.scene.Vertices); //var sampleN = TriangleNormal; //var N = n; Vector wi = samplePoint - point; //wi.Normalize(); float distanceSquared = wi.Length2(); float distance = MathLab.Sqrt(distanceSquared); wi /= distance; var nw = -wi; float sampleNdotMinusWi = Normal.Dot(ref TriangleNormal, ref nw); float NdotWi = Normal.Dot(ref n, ref wi); if ((sampleNdotMinusWi <= 0f) || (NdotWi <= 0f)) { tries++; if (tries > maxTries) { pdf = 0f; ray = new RayInfo(Point.Zero, Vector.Zero); return RgbSpectrum.ZeroSpectrum(); } goto startTry; } ray = new RayInfo(point, wi, MathLab.RAY_EPSILON, distance - MathLab.RAY_EPSILON); pdf = (distanceSquared / (sampleNdotMinusWi * meshArea)) * (1f / Math.Max(1, tries + 1)); // Using 0.01 instead of 0.0 to cut down fireflies if (pdf <= 0.01f) { pdf = 0f; return RgbSpectrum.ZeroSpectrum(); } return gain * meshArea; }
public abstract bool IntersectP(RayInfo ray, out float t0, out float t1);
public RayDifferential(RayInfo vray) : base(vray) { hasDifferentials = false; }
public RgbSpectrum SamplePhoton(SceneGeometryInfo scene, float u0, float u1, float u2, float u3, float u4, out float pdf, out RayInfo ray) { float b0, b1, b2; Point orig; var tri = SampleTriangle(u4); tri.Sample(ref mesh.scene.Vertices, u0, u1, out orig, out b0, out b1, out b2); var TriangleNormal = NormalModifier * tri.ComputeNormal(ref mesh.scene.Vertices); var area = tri.AreaV(ref mesh.scene.Vertices); // Ray direction var sampleN = TriangleNormal; Vector dir = MC.UniformSampleSphere(u2, u3); float RdotN = Normal.Dot(ref dir, ref sampleN); if (RdotN < 0f) { dir *= -1f; RdotN = -RdotN; } ray = new RayInfo(orig, dir); pdf = (MathLab.INVTWOPI / area) * (1f / mesh.TrianglesCount); return (gain * RdotN); }
//Transform WorldToVolume; public override bool IntersectP(RayInfo ray, out float t0, out float t1) { return this.worldBound.Intersect(ray, out t0, out t1); }
public void GetRay(double xp, double yp, out IRay cameraRay) { var u = (float)(2.0f * xp / w - 1.0f); var v = (float)(1.0f - 2.0f * yp / h); Vector rdir = mRight * u + mUp * v + this.Look; var rorig = (Position + rdir * 0.1f); rdir.Normalize(); cameraRay = new RayInfo(rorig, rdir); }
private RgbSpectrum Shade(MediumInfo currentMedium, float weight, RayInfo vray, IntersectionInfo isect, int depth) { var txtn = isect.GeometryInfo.GeoNormal; var p = isect.GeometryInfo.HitPoint; Vector v1, v2; Vector.CoordinateSystem(ref txtn, out v1, out v2); var Radiance = BaseColor * Vector.AbsDot(ref txtn, ref vray.Dir); for (int i = 0; i < shadowRayCount; i++) { var dir = MC.CosineSampleHemisphere(rnd.Value.NextFloat(), rnd.Value.NextFloat()); dir = new Vector(v1.x * dir.x + v2.x * dir.y + txtn.x * dir.z, v1.y * dir.x + v2.y * dir.y + txtn.y * dir.z, v1.z * dir.x + v2.z * dir.y + txtn.z * dir.z); stats.intersections++; if (!manager.Intersect(new RayInfo(p, dir, 1e-4f, maxOcclussionRayLength))) { Radiance += AddedRadiance * (1.0f / shadowRayCount); } } return Radiance; }
private bool IntersectNode(Node node, ref RayInfo ray) { if (node == null) { return false; } float t1 = 0f, u = 0f, v = 0f; if (IntersectBox(node.Bound, ref ray)) { //ray.MinT = t0; // ray.MaxT = t1; if (node.nPrims > 0) { for (var np = node.StartOffset; np < (node.StartOffset + node.nPrims); np++) { if (Intersect(ref triangles[np], sceneVertices, ref ray, ref t1, ref u, ref v)) { return true; } } } return IntersectNode(node.Left, ref ray) || IntersectNode(node.Right, ref ray); } return false; }
protected PathVertex[] PropagatePath(RayInfo startRay, int maxPaths) { IntersectionInfo isect; var vertices = new PathVertex[maxPaths]; var ray = new RayInfo(startRay); var sm = rnd.Value; for (int i = 0; i < maxPaths; i++) { Interlocked.Increment(ref stats.totalRays); if (manager.Intersect(ray, out isect)) { var vertice = new PathVertex { Wi = -ray.Dir }; Interlocked.Increment(ref stats.intersections); var triangle = GetTriangle(isect.PrimitiveId, isect.PrimitiveIndex); if (IsLight(triangle)) { var lt = GetLight(triangle.Owner); vertice.Emittance = lt.Le(ray.Dir); vertices[i] = (vertice); break; } vertice.Intersection = isect; var bsdf = matLib.GetSurfMat(isect.Material.Name); vertice.Bsdf = bsdf.First; var t = RgbSpectrum.Unit; vertice.BsdfSample = bsdf.Sample_f(ref vertice.Wi, out vertice.Wo, ref isect.GeometryInfo.GeoNormal, ref isect.GeometryInfo.ShadingNormal, ref t, sm.NextFloat(), sm.NextFloat(), sm.NextFloat(), ref isect.TextureData , out vertice.BsdfPdf, out vertice.SpecularBounce); vertices[i] = (vertice); ray = new RayInfo(isect.GeometryInfo.HitPoint, vertice.Wo); } else { vertices[i] = (new PathVertex() { Wi = -ray.Dir }); break; } } return vertices; }
public abstract RgbSpectrum tau(RayInfo ray, float step = 1f, float offset = 0.5f);
public static RgbSpectrum EstimateDirect(ref Vector wo, IAccellerationStructure intersector, SceneGeometryInfo scene, ILight light, IntersectionInfo isect, SurfaceBsdf bsdf, FastRandom rnd) { RgbSpectrum Ld = new RgbSpectrum(); Vector wi; float lightPdf, bsdfPdf; RayInfo shadowRay; RgbSpectrum Li = light.Sample(ref isect.GeometryInfo.HitPoint, ref isect.GeometryInfo.GeoNormal, rnd.NextFloat(), rnd.NextFloat(), rnd.NextFloat(), out shadowRay, out lightPdf); if (lightPdf > 0f && !Li.IsBlack()) { wi = -shadowRay.Dir; RgbSpectrum f ; bsdf.f(ref wo, ref wi, ref isect.GeometryInfo.GeoNormal, ref Ld, out f); if (!f.IsBlack() && !intersector.Intersect(shadowRay)) { // Add light's contribution to reflected radiance //Li *= visibility.Transmittance(scene, renderer, NULL, rng, arena); if (light.IsDelta) Ld += f * Li * (Vector.AbsDot(ref wi, ref isect.GeometryInfo.GeoNormal) / lightPdf); else { bsdfPdf = bsdf.Pdf(ref wo, ref wi, BxDFTypes.BSDF_ALL_TYPES); float weight = MC.PowerHeuristic(1, lightPdf, 1, bsdfPdf); Ld += f * Li * (Vector.AbsDot(ref wi, ref isect.GeometryInfo.GeoNormal) * weight / lightPdf); } } } if (!light.IsDelta) { //float bsdfPdf; bool spb; BsdfSampleData result; bsdf.Sample_f(ref wo, ref isect.GeometryInfo.GeoNormal, ref isect.GeometryInfo.ShadingNormal, ref Ld, rnd.NextFloat(), rnd.NextFloat(), rnd.NextFloat(), ref isect.TextureData, out result); bsdfPdf = result.Pdf; if (!result.F.IsBlack() && result.Pdf > 0f) { if (lightPdf > 0f) { float weight = MC.PowerHeuristic(1, bsdfPdf, 1, lightPdf); IntersectionInfo lightIsect; RgbSpectrum li = new RgbSpectrum(); var ray = new RayInfo(isect.GeometryInfo.HitPoint, result.Wi, 1e-4f, 1e+4f); if (intersector.Intersect(ray, out lightIsect)) { if (light is TriangleLight && lightIsect.PrimitiveId.Equals(((TriangleLight)light).Owner.Id)) li = light.Le(-result.Wi); } else li = light.Le(ray.Dir); if (!li.IsBlack()) { //Li *= scene->Transmittance(ray); Ld += result.F * li * Vector.AbsDot(ref result.Wi, ref isect.GeometryInfo.GeoNormal) * weight / bsdfPdf; } } } } /* if (!light->IsDeltaLight()) { BxDFType flags = BxDFType(BSDF_ALL & ~BSDF_SPECULAR); Spectrum f = bsdf->Sample_f(wo, &wi, bs1, bs2, bcs, &bsdfPdf, flags); if (!f.Black() && bsdfPdf > 0.) { lightPdf = light->Pdf(p, n, wi); if (lightPdf > 0.) { // Add light contribution from BSDF sampling float weight = PowerHeuristic(1, bsdfPdf, 1, lightPdf); Intersection lightIsect; Spectrum Li(0.f); RayDifferential ray(p, wi); if (scene->Intersect(ray, &lightIsect)) { if (lightIsect.primitive->GetAreaLight() == light) Li = lightIsect.Le(-wi); } else Li = light->Le(ray); if (!Li.Black()) { Li *= scene->Transmittance(ray); Ld += f * Li * AbsDot(wi, n) * weight / bsdfPdf; } } } } */ return Ld; }
public void GenerateRay(float xp, float yp, out RayInfo ray) { var u = 2.0f * xp / Width - 1.0f; var v = 1.0f - 2.0f * yp / Height; Vector rdir = x * u + y * v + dir; var rorig = (Position + rdir * 0.1f); rdir.Normalize(); ray = new RayInfo(rorig, -rdir); }
public RgbSpectrum Sample(ref Point point, ref Normal n, float u0, float u1, float u2, out RayInfo ray, out float pdf) { var wi = MC.CosineSampleHemisphere(u1, u2); pdf = wi.z * MathLab.INVPI; Vector v1, v2; Vector.CoordinateSystem(n.ToVec(), out v1, out v2); wi = new Vector( v1.x * wi.x + v2.x * wi.y + n.x * wi.z, v1.y * wi.x + v2.y * wi.y + n.y * wi.z, v1.z * wi.x + v2.z * wi.y + n.z * wi.z); ray = new RayInfo(point, wi, 1e-4f, float.MaxValue); return Le(wi); }
public RgbSpectrum Sample(ref Point point, ref Normal n, float u0, float u1, float u2, out RayInfo ray, out float pdf) { var l = Position - point + MC.UniformSampleSphere(u0, u1) * Radius; // vector to random point on source var Dist = l.Length; // distance to light source var Attenuation = 17f / Dist; // distance attenuation of light pdf = MC.UniformSpherePdf(); ray = new RayInfo(point, l / Dist, 1e-4f, Dist - 1e-4f); return (Power*Radius / Dist); }
public static bool IntersectBox(BBox box, RayInfo ray) { float t0 = ray.Min; float t1 = ray.Max; var rayInvDir = 1f / ray.Dir; //1f /ray.Dir; float invDirX = rayInvDir.x; if (!process_box_coord(ref t0, ref t1, box.Min.x - ray.Org.x, box.Max.x - ray.Org.x, invDirX)) return false; float invDirY = rayInvDir.y; if (!process_box_coord(ref t0, ref t1, box.Min.y - ray.Org.y, box.Max.y - ray.Org.y, invDirY)) return false; float invDirZ = rayInvDir.z; if (!process_box_coord(ref t0, ref t1, box.Min.z - ray.Org.z, box.Max.z - ray.Org.z, invDirZ)) return false; return true; }
public bool IntersectLBVH(ref RayInfo ray, ref RayHit sp) { int currentNode = 0; float u = 0f, v = 0f, t1 = float.MaxValue, dist = float.MaxValue; bool hit = false; int stopNode = gpuBvhTree[0].SkipOffset; sp.Index = RayBuffer.NotHit; while (currentNode < stopNode) { if (BBox.IntersectBox(ref gpuBvhTree[currentNode].Bound, ref ray)) { if (gpuBvhTree[currentNode].PrimOffset != 0) { if (Intersect(ref triangles[gpuBvhTree[currentNode].PrimOffset], sceneVertices, ref ray, ref t1, ref u, ref v)) { var triangleIndex = gpuBvhTree[currentNode].PrimOffset; dist = t1; sp.Index = (uint)(triangleIndex); sp.Distance = dist; sp.U = u; sp.V = v; hit = true; } } currentNode++; } else { currentNode = gpuBvhTree[currentNode].SkipOffset; } } return hit; }
private RgbSpectrum Trace(RayInfo ray, float weight, MediumInfo currentMedium, int depth) { IntersectionInfo isect; //RaysTraced++; stats.totalRays++; var color = new RgbSpectrum(0f); if (manager.Intersect(ray, out isect)) { stats.intersections++; //Intersections++; color = this.Shade(currentMedium, weight, ray, isect, depth); } else { color = this.ShadeBackground(ray); } return color; }
public bool Intersect(ref Point[] meshVertices, ref RayInfo ray, ref float thit, ref float u, ref float v) { Vector s1; if (!edgesInitialized) { Point.Sub(ref meshVertices[v1], ref meshVertices[v0], out e1); Point.Sub(ref meshVertices[v2], ref meshVertices[v0], out e2); edgesInitialized = true; } Vector.Cross(ref ray.Dir, ref e2, out s1); var divisor = Vector.Dot(ref s1, ref e1); if (divisor < MathLab.Epsilon) return false; var invDivisor = 1f / divisor; Vector d, s2; d = ray.Org - meshVertices[v0]; //Point.Sub(ref ray.Org, ref meshVertices[v0], out d); var b1 = Vector.Dot(ref d, ref s1) * invDivisor; if (b1 < 0f) return false; Vector.Cross(ref d, ref e1, out s2); var b2 = Vector.Dot(ref ray.Dir, ref s2) * invDivisor; if (b2 < 0f) return false; var b0 = 1f - b1 - b2; if (b0 < 0f) return false; var t = Vector.Dot(ref e2, ref s2) * invDivisor; if (t < ray.MinT || t > ray.MaxT) return false; thit = t; u = b1; v = b2; return true; }
private bool IntersectBVH(ref RayInfo ray, ref RayHit sp) { if (bvhTree.Length == 0) return false; int triangleIndex = -1; float u = 0f, v = 0f; bool hit = false; Vector invDir = ray.InvDirection; //new Vector(1f / ray.Dir.x, 1f / ray.Dir.y, 1f / ray.Dir.z); var dirIsNeg = new[] { invDir.x < 0, invDir.y < 0, invDir.z < 0 }; int todoOffset = 0, nodeNum = 0; int[] todo = new int[TraversalStackSize]; var dist = float.MaxValue; while (true) { var node = bvhTree[nodeNum]; float t1 = 0f; if (BBox.IntersectBox(ref node.Bound, ref ray)) { //if (node.bbox.Intersect(vray, out t0, out t2)) { if (node.PrimitiveCount > 0) { for (var i = 0; i < node.PrimitiveCount; ++i) { if (Intersect(ref triangles[node.PrimOffset + i], sceneVertices, ref ray, ref t1, ref u, ref v)) { if (dist > t1) { triangleIndex = node.PrimOffset + i; dist = t1; sp.Index = (uint)(triangleIndex); sp.Distance = dist; sp.U = u; sp.V = v; hit = true; } } } if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } else { if (dirIsNeg[node.Axis]) { todo[todoOffset++] = nodeNum + 1; nodeNum = node.SecondChildOffset; } else { todo[todoOffset++] = node.SecondChildOffset; nodeNum = nodeNum + 1; } } } else { if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } } if (hit) { return true; } sp.Index = RayBuffer.NotHit; return false; }
public static bool IntersectBox(AABB box, RayInfo ray) { float t0 = ray.minT; float t1 = ray.maxT; //float hitt0 = t0; //float hitt1 = t1; if (!process_box_coord(ref t0, ref t1, box.Min.x - ray.Org.x, box.Max.x - ray.Org.x, 1f / ray.Dir.x)) return false; if (!process_box_coord(ref t0, ref t1, box.Min.y - ray.Org.y, box.Max.y - ray.Org.y, 1f / ray.Dir.y)) return false; if (!process_box_coord(ref t0, ref t1, box.Min.z - ray.Org.z, box.Max.z - ray.Org.z, 1f / ray.Dir.z)) return false; /* for (int i = 0; i < 3; ++i) { // Update interval for _i_th bounding box slab float invRayDir = 1f / ray.Direction[i]; if (!process_box_coord(ref t0, ref t1, min[i] - ray.Origin[i], max[i] - ray.Origin[i], invRayDir)) return false; } * */ //ray.MinT = t0; //ray.MaxT = t1; //hitt0 = t0; //hitt1 = t1; return true; }
private bool ShadowIntersectBVH(ref RayInfo ray) { if (nodes.Count == 0) return false; bool hit = false; Vector invDir = ray.InvDirection; //new Vector(1f / ray.Dir.x, 1f / ray.Dir.y, 1f / ray.Dir.z); var dirIsNeg = new[] { invDir.x < 0, invDir.y < 0, invDir.z < 0 }; int todoOffset = 0, nodeNum = 0; int[] todo = new int[TraversalStackSize]; while (true) { var node = bvhTree[nodeNum]; float t1 = 0f, u = 0f, v = 0f; if (BBox.IntersectBox(ref node.Bound, ref ray)) { if (node.PrimitiveCount > 0) { for (var i = 0; i < node.PrimitiveCount; ++i) { if (!Intersect(ref triangles[node.PrimOffset + i], sceneVertices, ref ray, ref t1, ref u, ref v)) continue; hit = true; break; } if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } else { if (dirIsNeg[node.Axis]) { todo[todoOffset++] = nodeNum + 1; nodeNum = node.SecondChildOffset; } else { todo[todoOffset++] = node.SecondChildOffset; nodeNum = nodeNum + 1; } } } else { if (todoOffset == 0) break; nodeNum = todo[--todoOffset]; } } return hit; }