/// <summary> /// Sample returns a single possible direction /// </summary> /// <param name="woL"></param> /// <returns></returns> public override (Spectrum, Vector3, double) Sample_f(Vector3 wo) { var F = fresnel.Evaluate(Utils.CosTheta(wo)); bool entering = Utils.CosTheta(wo) > 0; var etaI = entering ? fresnel.EtaI : fresnel.EtaT; var etaT = entering ? fresnel.EtaT : fresnel.EtaI; var n = new Vector3(0, 0, 1); n = Vector3.Dot(n, wo) < 0 ? -n : n; var(refracted, wt) = Refract(wo, n, etaI / etaT); if (!refracted) { return(Spectrum.ZeroSpectrum, null, 0); } Spectrum ft = r * (1 - F.Max()); var pdf = 1 - F.Max(); return(ft / Utils.AbsCosTheta(wt), wt, pdf); }
/// <summary> /// Sample returns a single possible direction /// </summary> /// <param name="woL"></param> /// <returns></returns> public override (Spectrum, Vector3, double) Sample_f(Vector3 woL) { // perfect specular reflection Vector3 wiL = new Vector3(-woL.x, -woL.y, woL.z); Spectrum ft = r * fresnel.Evaluate(Utils.CosTheta(wiL)); return(ft / Utils.AbsCosTheta(wiL), wiL, 1); }
public override Spectrum f(Vector3 wo, Vector3 wi) { Vector3 wh = wo + wi; if (wh.z < 0.0) { wi = -wi; wh = -wh; } if (wh.LengthSquared() == 0.0) // epsilon ? { return(Spectrum.ZeroSpectrum); } wh = wh.Normalize(); double cos_phi_h = Utils.CosPhi(wh); double sin_phi_h = Utils.SinPhi(wh); double cos_theta_h = Utils.CosTheta(wh); double sin_theta_h = Utils.SinTheta(wh); Vector3 w_hx = new Vector3(cos_phi_h * cos_theta_h, sin_phi_h * cos_theta_h, -sin_theta_h); Vector3 w_hy = new Vector3(-sin_phi_h, cos_phi_h, 0.0); Vector3 w_d = new Vector3(Vector3.Dot(wi, w_hx), Vector3.Dot(wi, w_hy), Vector3.Dot(wi, wh)); double theta_h = SphericalTheta(wh); double theta_d = SphericalTheta(w_d); double phi_d = SphericalPhi(w_d); if (phi_d > Math.PI) { phi_d = phi_d - Math.PI; } // Get i. int theta_h_idx = ThetaHalfIndex(theta_h); int theta_d_idx = ThetaDiffIndex(theta_d); int phi_d_idx = PhiDiffIndex(phi_d); int i = phi_d_idx + (BRDF_SAMPLING_RES_PHI_D / 2) * (theta_d_idx + theta_h_idx * BRDF_SAMPLING_RES_THETA_D); return(Spectrum.Create(Vector <double> .Build.Dense(new[] { brdf[3 * i], brdf[3 * i + 1], brdf[3 * i + 2] }))); }