public override void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2, out IColorType radiance, out float pdf, out RayData ray) { var wi = MC.CosineSampleHemisphere(u1, u2); pdf = wi.z * MathLab.INVPI; wi = pt.Frame.ToWorld(ref wi); ray = new RayData(ref pt.HitPoint, ref wi, 1e-4f, float.MaxValue); radiance = Le(ref wi); }
public override void F(ShadePointInfo pt, out IColorType fs, BrdfType types = BrdfType.Diffuse) { float c = 1f - Vector.Dot(ref pt.IncomingDirection, ref pt.ShadingNormal); float Re = R0 + (1f - R0) * c * c * c * c * c; float P = .25f + .5f * Re; fs = pt.Diffuse.CloneValue().Mul(MathLab.INVPI).Mul((1f - Re) / (1f - P)); }
public override void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2, out IColorType radiance, out float pdf, out RayData ray) { var dir = -(Position - pt.HitPoint); var l2 = dir.Length2(); var l = MathLab.Sqrt(l2); dir.Normalize(); pdf = MC.UniformSpherePdf(); ray = new RayData(ref pt.HitPoint, ref dir, 1e-4f, l - 1e-4f); radiance = power.Mul(1f / l); //float theta = Vector.SphericalTheta(ref dir); //Profile.Evaluate(Vector.SphericalPhi(ref dir) * MathLab.INVTWOPI, theta * MathLab.INVPI); }
public override void Sample_f(ShadePointInfo pt, float u0, float u1, float u2, out Vector vector, out float radiancePdf, out float pdf1, out BsdfEvent @event) { float c = 1f - Vector.Dot(ref pt.IncomingDirection, ref pt.ShadingNormal); float Re = R0 + (1f - R0) * c * c * c * c * c; float P = .25f + .5f * Re; if ((u2 < P && reflectionSpecularBounce)) {//onlySpecular || vector = MetalBrdf.GlossyReflection(ref pt.IncomingDirection, exponent, ref pt.ShadingNormal, u0, u1); pdf1 = P / Re; @event = BsdfEvent.Specular; radiancePdf = Re; } else { Vector dir = MC.CosineSampleHemisphere(u0, u1); pdf1 = dir.z * MathLab.INVPI; /* Vector v1, v2; * dir = Vector.CoordinateSystem(ref shadeN, out v1, out v2); dir = new Vector( v1.x * dir.x + v2.x * dir.y + shadeN.x * dir.z, v1.y * dir.x + v2.y * dir.y + shadeN.y * dir.z, v1.z * dir.x + v2.z * dir.y + shadeN.z * dir.z);*/ ONB fm = new ONB(ref pt.ShadingNormal); var wi = fm.ToWorld(ref dir);//pt.Frame float dp = Vector.Dot(ref pt.ShadingNormal, ref wi); // Using 0.0001 instead of 0.0 to cut down fireflies if (dp <= 0.0001f) { pdf1 = 0f; } pdf1 /= dp; float iRe = 1f - Re; pdf1 *= (1f - P) / iRe; @event = BsdfEvent.Glossy | BsdfEvent.Diffuse; vector = wi; radiancePdf = iRe; } }
public override void Sample_f(ShadePointInfo point, float u0, float u1, float u2, out Vector wi, out float radiance, out float pdf, out BsdfEvent bsdfEvent) { Vector dir = MC.CosineSampleHemisphere(u0, u1); pdf = dir.z * MathLab.INVPI; bsdfEvent = BsdfEvent.Diffuse; wi = point.Frame.ToWorld(ref dir); float dp = (Normal.Dot(ref point.GeoNormal, ref wi)); if (dp <= 0.01f) { pdf = 0f; bsdfEvent = BsdfEvent.Absorb; radiance = 0f; } else { pdf /= dp; radiance = MathLab.INVPI; } }
public abstract void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2, out IColorType radiance, out float pdf, out RayData ray);
public override void Sample_f(ShadePointInfo pt, float u0, float u1, float u2, out Vector Wi, out float radiancePdf, out float pdf, out BsdfEvent @event) { Vector rayDir = -pt.IncomingDirection; var N = pt.GeoNormal; var shadeN = pt.ShadingNormal; var wi = new Vector(); var N1 = N.ToVec(); var reflDir = rayDir - (2f * (Normal.Dot(ref N, ref rayDir))) * N1; // Ray from outside going in ? bool into = ((Normal.Dot(ref N, ref shadeN)) > 0); float nc = n0; float nt = n1; float nnt = into ? (nc / nt) : (nt / nc); float ddn = (rayDir & shadeN.ToVec()); float cos2t = 1f - nnt * nnt * (1f - ddn * ddn); radiancePdf = 0f; // Total internal reflection if (cos2t < 0f) { wi = reflDir; pdf = 1f; @event = BsdfEvent.Reflect | BsdfEvent.Specular; radiancePdf = 1f; Wi = wi; return; } float kk = (into ? 1f : -1f) * (ddn * nnt + MathLab.Sqrt((cos2t))); Vector nkk = kk * N1; Vector transDir = (nnt * rayDir - nkk).Normalize(); float c = 1f - (into ? -ddn : (transDir & N1)); float Re = R0 + (1f - R0) * c * c * c * c * c; float Tr = 1f - Re; float P = .25f + .5f * Re; if (Tr.NearEqual(0f)) { if (Re.NearEqual(0f)) { pdf = 0f; @event = BsdfEvent.Absorb; } else { (wi) = reflDir; pdf = 1f; radiancePdf = 1f; @event = BsdfEvent.Reflect | BsdfEvent.Specular; Wi = wi; return; } } else if (Re.NearEqual(0f)) { (wi) = transDir; pdf = 1f; @event = BsdfEvent.Transmit | BsdfEvent.Specular; radiancePdf = 1.0f; } else if (u0 < P) { (wi) = reflDir; pdf = P / Re; radiancePdf = 1f; @event = BsdfEvent.Reflect | BsdfEvent.Specular; } else { (wi) = transDir; pdf = (1f - P) / Tr; @event = BsdfEvent.Transmit | BsdfEvent.Specular; radiancePdf = 1.0f; } Wi = wi; }
public override void F(ShadePointInfo pt, out IColorType fs, BrdfType types = BrdfType.Diffuse) { throw new NotImplementedException(); }
public BrdfBase GetBrdf(ShadePointInfo point, float u0, out float pdf) { pdf = 1f; return this.brdf; }
public override void F(ShadePointInfo pt, out IColorType fs, BrdfType types = BrdfType.Diffuse) { fs = pt.Diffuse.Mul(MathLab.INVPI); }
public override void EvaluateShadow(ShadePointInfo pt, float u0, float u1, float u2, out IColorType radiance, out float pdf,out RayData ray) { int tries = 0; #if VERBOSE try { #endif ray = new RayData() {Org = pt.HitPoint}; Point samplePoint; float b0, b1, b2; int maxTries = 1; startTry: var index = Math.Max(0, Math.Min(triangleSampleData.Length - 1, (int)(u0 * (mesh.EndTriangle - mesh.StartTriangle)))); Sample(ref scene.Triangles[mesh.StartTriangle + index], scene.Vertices, u2, u1, out samplePoint, out b0, out b1, out b2); var u = b0; var v = b1; var triangleNormal = triangleSampleData[index].Item2; var area = triangleSampleData[index].Item1; //tri.AreaV(scene.Vertices); //var sampleN = TriangleNormal; //var N = n; Vector wi = samplePoint - pt.HitPoint; //wi.Normalize(); float distanceSquared = wi.Length2(); var distance = MathLab.Sqrt(distanceSquared); wi /= distance; var nw = -wi; float sampleNdotMinusWi = Normal.Dot(ref triangleNormal, ref nw); float NdotWi = Normal.Dot(ref pt.GeoNormal, ref wi); if ((sampleNdotMinusWi <= 0f) || (NdotWi <= 0f)) { tries++; if (tries > maxTries) { pdf = 0f; radiance = ColorManager.Instance.Zero(); return; } goto startTry; } pdf = //((1f / area) * distanceSquared / sampleNdotMinusWi) * (1f / mesh.TrianglesCount) * (1f / Math.Max(1, tries + 1)); (distanceSquared / (sampleNdotMinusWi * area)) * 1f / mesh.TrianglesCount * (1f / Math.Max(1, tries + 1)); // Using 0.01 instead of 0.0 to cut down fireflies if (pdf <= 0.01f) { pdf = 0f; radiance = ColorManager.Instance.Zero(); return; } float lp; radiance = Material.GetEmittance(u, v, out lp); ray.Dir = wi; //, MathLab.RAY_EPSILON, distance - MathLab.RAY_EPSILON); #if VERBOSE } catch (Exception ex) { Tracer.TraceLine(ex.Message + ex.StackTrace); Tracer.TraceLine("Triangle data offset " + (mesh.StartTriangle).ToString() + "of " + triangleSampleData.Length); throw ex; } #endif }