public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; Vector dir = MC.CosineSampleHemisphere(u0, u1); result.Pdf = dir.z * MathLab.INVPI; result.Type = BrdfType.Diffuse; Vector v1, v2; Normal n = N; Vector.CoordinateSystem(ref n, out v1, out v2); dir = new Vector( v1.x * dir.x + v2.x * dir.y + n.x * dir.z, v1.y * dir.x + v2.y * dir.y + n.y * dir.z, v1.z * dir.x + v2.z * dir.y + n.z * dir.z); var wi = dir; float dp = (Normal.Dot(ref shadeN, ref wi)); if (dp <= 0.01f) { result.Pdf = 0f; result.F = new RgbSpectrum(); } else { result.Pdf /= dp; result.F = surfaceData.Diffuse*MathLab.INVPI; } result.Wi = wi; }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { EvalParams(ref surfaceData); bool into = (Normal.Dot(ref N, ref shadeN) > 0f); result = new BsdfSampleData(); result.Type = this.Type; if (!into) { // No internal reflections result.Wi = (-wo); result.Pdf = 1f; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefl; } else { // RR to choose if reflect the ray or go trough the glass float comp = u0 * totFilter; if (comp > transFilter) { Vector mwo = -wo; result.Wi = mwo - (2f * Vector.Dot(ref N, ref mwo)) * N.ToVec(); result.Pdf = reflPdf; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefrct; } else { result.Wi = -wo; result.Pdf = transPdf; result.F = Krefrct; result.Type = transmitionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; } } }
public override void Sample_f(ref Vector wo, ref Normal geoNormal, ref Normal shadeN, float lambda, ref SurfaceTextureData surfaceData, float u0, float u1, float u2, out BsdfSampleData result) { EvalParams(ref surfaceData, lambda); Vector dir = MC.CosineSampleHemisphere(u0, u1); result = new BsdfSampleData { Pdf = dir.z*MathLab.INVPI, Type = BrdfType.Diffuse}; // TODO Lambda weight Vector v1, v2; Normal n = geoNormal; Vector.CoordinateSystem(ref n, out v1, out v2); dir = new Vector( v1.x * dir.x + v2.x * dir.y + n.x * dir.z, v1.y * dir.x + v2.y * dir.y + n.y * dir.z, v1.z * dir.x + v2.z * dir.y + n.z * dir.z); var wi = dir; float dp = (Normal.Dot(ref shadeN, ref wi)); // Using 0.01 instead of 0.0 to cut down fireflies if (dp <= 0.0001f) { result.Pdf = 0f; result.F = new RgbSpectrum(); result.Lambda = 0f; } else { result.Pdf /= dp; result.F = surfaceData.Diffuse * MathLab.INVPI; result.Lambda = Kd.Sample(lambda)*MathLab.INVPI; } result.Wi = wi; }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; Vector dir = MC.CosineSampleHemisphere(u0, u1); result.Pdf = dir.z * MathLab.INVPI; result.Type = BrdfType.Diffuse | BrdfType.Refractive; Vector v1, v2; Normal n = -N; Vector.CoordinateSystem(ref n, out v1, out v2); dir = new Vector( v1.x * dir.x + v2.x * dir.y + n.x * dir.z, v1.y * dir.x + v2.y * dir.y + n.y * dir.z, v1.z * dir.x + v2.z * dir.y + n.z * dir.z); var wi = dir; float dp = (Normal.AbsDot(ref n, ref wi)); // Using 0.01 instead of 0.0 to cut down fireflies if (dp <= 0.0001f) { result.Pdf /= 1000f; // return new RgbSpectrum(0f); } else { result.Pdf /= dp; } result.F= KdOverPI; result.Wi = wi; }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { Vector dir = -wo; float dp = Normal.Dot(ref shadeN, ref dir); result.Lambda = 0f; result.Wi = dir - (2f * dp) * shadeN.ToVec(); result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.Pdf = 1f; result.F = Kr; }
public virtual void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref SurfaceTextureData surfaceData, float u0, float u1, float u2, out BsdfSampleData result) { result = new BsdfSampleData() {Type = this.Type}; CreateFrame(ref N); var wi = MC.CosineSampleHemisphere(u1, u2); if (wo.z < 0f) wi.z *= -1f; this.EvalTexture(ref surfaceData); result.Pdf = Pdf(ref wo, ref wi, BxDFTypes.BSDF_ALL); f(ref wo, ref wi, ref shadeN, out result.F); result.Wi = LocalToWorld(ref wi); }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { float c = 1f - Vector.Dot(ref wo, ref shadeN); float Re = R0 + (1f - R0) * c * c * c * c * c; result = new BsdfSampleData(); float P = .25f + .5f * Re; EvalParams(ref surfaceData); if ((u2 < P)) {//onlySpecular || result.Wi = GlossyReflection(ref wo, exponent, ref shadeN, u0, u1); result.Pdf = P / Re; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Diffuse; result.F = Re * Krefl; } else { Vector dir = MC.CosineSampleHemisphere(u0, u1); result.Pdf = dir.z * MathLab.INVPI; Vector v1, v2; 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); var wi = dir; float dp = Vector.Dot(ref shadeN, ref wi); // Using 0.0001 instead of 0.0 to cut down fireflies if (dp <= 0.0001f) { result.Pdf = 0f; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Diffuse; result.F = new RgbSpectrum(); } result.Pdf /= dp; float iRe = 1f - Re; result.Pdf *= (1f - P) / iRe; result.Type = BrdfType.Glossy; result.Wi = wi; result.F = iRe * Kdiff; } }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { float comp = u2 * totFilter; if (comp > matteFilter) { mirror.Sample_f(ref wo, ref N, ref shadeN, ref in_f, u0, u1, u2, ref surfaceData, out result); result.Pdf *= mirrorPdf; } else { matte.Sample_f(ref wo, ref N, ref shadeN, ref in_f, u0, u1, u2, ref surfaceData, out result); result.Pdf *= mattePdf; } }
public override void Sample_f(ref Vector lwo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; CreateFrame(ref shadeN); var wo = WorldToLocal(ref lwo); //((wiW & ng) * (woW & ng) > 0f) if (Vector.Dot(ref lwo, ref N)> 0f) { var wi = new Vector(-wo.x, -wo.y, wo.z); var f = fresnel.Evaluate(CosTheta(ref wo)) * Kr /Math.Abs(CosTheta(ref wi)); result.Wi = LocalToWorld(wi); result.Pdf = 1.0f; result.Type = BrdfType.Specular; result.F = f; } else { bool entering = CosTheta(ref wo) > 0f; result.Type = BrdfType.Refractive; float ei = 1.0005f, et = Medium.IoR; if (!entering) MathLab.Swap(ref ei, ref et); // Compute transmitted ray direction float sini2 = SinTheta2(ref wo); float eta = ei / et; float sint2 = eta * eta * sini2; // Handle total internal reflection for transmission if (sint2 > 1f) { result.F = RgbSpectrum.ZeroSpectrum(); result.Pdf = 0f; result.Wi = new Vector(); }; float cost = MathLab.Sqrt(Math.Max(MathLab.Epsilon, 1f - sint2)); if (entering) cost = -cost; float sintOverSini = eta; var wi = new Vector(sintOverSini * -wo.x, sintOverSini * -wo.y, cost); result.Pdf = 1f; var F = fresnel.Evaluate(CosTheta(ref wo)); result.Wi = LocalToWorld(ref wi); result.F = (ei*ei)/(et*et) * (RgbSpectrum.UnitSpectrum()-F) * Kt /Math.Abs(Math.Max(MathLab.Epsilon, CosTheta(ref wi))); } }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; this.CreateFrame(ref shadeN); this.EvalParams(ref surfaceData); float phi = (float)Math.Atan(MathLab.Sqrt((1f + nu) / (1f + nv)) * Math.Tan(u0 * MathLab.M_PI)); float p = (float)(nu * Math.Cos(phi) * Math.Cos(phi) + nu * Math.Sin(phi) * Math.Sin(phi)); float cosp = (float)MathLab.Pow(1.0 - u1, 1.0 / p); var wi = Vector.SphericalDirection(MathLab.Sin(phi), MathLab.Cos(phi), (float)Math.Acos(cosp)); var wh = (wo + wi).Normalize(); result.Type = BrdfType.Glossy; result.Pdf = (MathLab.Sqrt((nu + 1f) * (nv + 1f)) / 2f * MathLab.M_PI) * Vector.Dot(ref wh, ref N) * p; result.Pdf /= 4f * Vector.Dot(ref wo, ref wh); this.EvalBrdf(ref wo, ref wi, ref N, out result.F); result.Wi = LocalToWorld(ref wi); }
public override void Sample_f(ref Vector lwo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; this.R0 = surfaceData.Diffuse; result.Type = BrdfType.Glossy; Vector wi; CreateFrame(ref shadeN); var wo = WorldToLocal(ref lwo); distr.Sample_f(ref wo, out wi, u0, u1, out result.Pdf); result.Wi = LocalToWorld(ref wi); if (!SameHemisphere(ref wo, ref wi)) result.F = RgbSpectrum.ZeroSpectrum(); //new RgbSpectrum(1f, 0f,0f); else { RgbSpectrum fs; EvalBrdf(ref wo, ref wi, ref shadeN, out fs); result.F = fs; } }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; EvalParams(ref surfaceData); CreateFrame(ref shadeN); Vector dir = MC.CosineSampleHemisphere(u0, u1).Normalize(); result.Pdf = dir.z * MathLab.INVPI; result.Type = BrdfType.Diffuse; //Vector v1, v2; //Normal n = N; //Vector.CoordinateSystem(ref n, out v1, out v2); var wi = LocalToWorld(ref dir); /*new Vector( v1.x * dir.x + v2.x * dir.y + n.x * dir.z, v1.y * dir.x + v2.y * dir.y + n.y * dir.z, v1.z * dir.x + v2.z * dir.y + n.z * dir.z);*/ float dp = (Normal.Dot(ref shadeN, ref wi)); // Using 0.01 instead of 0.0 to cut down fireflies if (dp <= 0.0001f) { result.Pdf = 0f; result.F = new RgbSpectrum(0f); } result.Pdf /= dp; RgbSpectrum fs; var lwo = WorldToLocal(ref wo).Normalize(); EvalBrdf(out fs, ref dir, ref lwo); result.Wi = wi; result.F = fs; }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { EvalParams(ref surfaceData); result = new BsdfSampleData() { Type = this.Type }; CreateFrame(ref N); var wi = MC.CosineSampleHemisphere(u1, u2); if (wo.z < 0f) wi.z *= -1f; result.Pdf = Pdf(ref wo, ref wi, BxDFTypes.BSDF_ALL); EvalBrdf(out result.F, ref wo, ref wi ); wi = LocalToWorld(ref wi); result.Wi = wi; // return f(wo, *wi); }
public override void Sample_f(ref Vector wo, ref Normal Normal, ref Normal shadeNormal, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; EvalParams(ref surfaceData); Assert.IsTrue(!Krefl.IsBlack()); Assert.IsTrue(!Krefrct.IsBlack()); Vector rayDir = -wo; var N = shadeNormal; var shadeN = shadeNormal; 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 = ousideIor; bool disperse = in_f.y() > u0; float nt = ior + (disperse ? (1f - in_f.y())/10f : 0f); if (disperse) { Krefrct = in_f.MaxAsSingle()*in_f; //SampledSpectrum.ReflRainbow[(int) Math.Round((SampledSpectrum.ReflRainbow.Length-1)*u2)]; } float nnt = into ? (nc / nt) : (nt / nc); float ddn = (rayDir & shadeN.ToVec()); float cos2t = 1f - nnt * nnt * (1f - ddn * ddn); result.F = RgbSpectrum.UnitSpectrum(); // Total internal reflection if (cos2t < 0f) { wi = reflDir; result.Pdf = 1f; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefl; result.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)) { result.Pdf = 0f; result.Type = BrdfType.Specular; result.F = new RgbSpectrum(0f); } else { (wi) = reflDir; result.Pdf = 1f; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefl; } } else if (Re.NearEqual(0f)) { (wi) = transDir; result.Pdf = 1f; result.Type = transmitionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefrct; } else if (u0 < P) { (wi) = reflDir; result.Pdf = P / Re; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefl; } else { if (u0 > u1) { //(wi) = SampleTransmissionDirection(u0, u1, ref transDir); wi = transDir; result.F = Krefrct; //SampleTransmission(u1, u2, ref Krefrct); } else { wi = transDir; result.F = Krefrct; } result.Pdf = (1f - P) / Tr; result.Type = transmitionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; } result.Wi = wi; }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { base.Sample_f(ref wo, ref N, ref shadeN, ref in_f, u0, u1, u2, ref surfaceData, out result); result.Wi = new Vector(result.Wi.x, result.Wi.y, -result.Wi.z); }
public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; EvalParams(ref surfaceData); CreateFrame(ref shadeN); float bdf; var wi = sample_phong_lobe(u0, u1, exp, out result.Pdf, out bdf, ref nn, ref sn, ref tn); result.Wi = LocalToWorld(ref wi); result.Type = BrdfType.Glossy | BrdfType.Diffuse; result.F = EvalBrdf(ref wo, ref wi, ref shadeN); }
public override void Sample_f(ref Vector wo, ref Normal Normal, ref Normal shadeNormal, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { result.Lambda = 0f; result.Type = this.Type; EvalParams(ref surfaceData); #if VERBOSE Assert.IsTrue(!Krefl.IsBlack()); Assert.IsTrue(!Krefrct.IsBlack()); #endif Vector rayDir = -wo; var N = shadeNormal; var shadeN = shadeNormal; 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 = ousideIor; float nt = ior; float nnt = into ? (nc / nt) : (nt / nc); float ddn = (rayDir & shadeN.ToVec()); float cos2t = 1f - nnt * nnt * (1f - ddn * ddn); result.F = RgbSpectrum.UnitSpectrum(); // Total internal reflection if (cos2t < 0f) { wi = reflDir; result.Pdf = 1f; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefl; result.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)) { result.Pdf = 0f; result.Type = BrdfType.Specular; result.F = new RgbSpectrum(0f); } else { (wi) = reflDir; result.Pdf = 1f; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefl; } } else if (Re.NearEqual(0f)) { (wi) = transDir; result.Pdf = 1f; result.Type = transmitionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefrct; } else if (u0 < P) { (wi) = reflDir; result.Pdf = P / Re; result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefl; } else { (wi) = transDir; result.Pdf = (1f - P) / Tr; result.Type = transmitionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy; result.F = Krefrct; } result.Wi = wi; }
//public override void Sample_f(ref Vector wo, out Vector wi, ref Normal N, ref Normal shadeN, float u0, float u1, float u2, ref RgbSpectrum col, out BsdfSampleData result1) //{ // RgbSpectrum temp = Kr; // Kr = col; // this.Sample_f(ref wo, ref N, ref shadeN, u0, u1, u2, ref hitInfo.TextureData, out result1); // Kr = temp; // wi = result1.Wi; //} public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) { if (surfaceData != null) { exponent = 1f/(surfaceData.Exponent + 1f); } result = new BsdfSampleData(); result.Wi = GlossyReflection(ref wo, exponent, ref shadeN, u0, u1); result.Type = this.Type; if (Vector.Dot(ref result.Wi, ref shadeN) > 0f) { result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Diffuse; result.Pdf = 1f; result.F = surfaceData != null ? RgbSpectrum.Max(ref surfaceData.Specular, ref Kr) : Kr; } else { result.F = new RgbSpectrum(0f); result.Pdf = 0f; result.Type = BrdfType.Diffuse; } /* float phi = 2f * MathLab.M_PI * u0; float cosTheta = (float)Math.Pow(1f - u1, exponent); float sinTheta = MathLab.Sqrt(1f - cosTheta * cosTheta); float x = (float)Math.Cos(phi) * sinTheta; float y = (float)Math.Sin(phi) * sinTheta; float z = cosTheta; Vector dir = -wo; float dp = (Normal.Dot(ref shadeN, ref dir)); Vector w = dir - (2f * dp) * (shadeN.ToVec()); Vector u; if (Math.Abs(shadeN.x) > .1f) { Vector a = new Vector(0f, 1f, 0f); u = (a ^ w); } else { Vector a = new Vector(1f, 0f, 0f); u = (a ^ w); } u.Normalize(); Vector v = (w ^ u); wi = x * u + y * v + z * w; if ((wi & shadeN.ToVec()) > 0f) { specularBounce = reflectionSpecularBounce; pdf = 1f; return Kr; } else { pdf = 0f; specularBounce = reflectionSpecularBounce;//!! return new RgbSpectrum(0f); }*/ }
public abstract void Sample_f(ref Vector wo, ref Normal geoNormal, ref Normal shadeN, float lambda, ref SurfaceTextureData surfaceData, float u0, float u1, float u2, out BsdfSampleData result);