public override Spectrum f(Vector3 wo, Vector3 wi) { if (!Utils.SameHemisphere(wo, wi)) { return(Spectrum.ZeroSpectrum); } // Cos term // Adicijski izrek: cos(x +- y) = cos(x) * cos(y) -+ sin(x) * sin(y) double cosDiff = Utils.CosPhi(wi) * Utils.CosPhi(wo) + Utils.SinPhi(wi) * Utils.SinPhi(wo); // Sin and tan terms double sinAlpha, tanBeta; if (Utils.AbsCosTheta(wi) > Utils.AbsCosTheta(wo)) // oTheta > iTheta { sinAlpha = Utils.SinTheta(wo); tanBeta = Utils.SinTheta(wi) / Utils.AbsCosTheta(wi); } else // iTheta >= oTheta { sinAlpha = Utils.SinTheta(wi); tanBeta = Utils.SinTheta(wo) / Utils.AbsCosTheta(wo); } return(kd * Utils.PiInv * (A + B * Math.Max(0, cosDiff) * sinAlpha * tanBeta)); }
public override Spectrum f(Vector3 wo, Vector3 wi) { double a = 1 - ((roughness2 / 2 * (roughness2 + 0.33))); double b = 0.45 * roughness2 / (roughness2 + 0.09); double sinThetaI = Utils.SinTheta(wi); double sinThetaO = Utils.SinTheta(wo); double sinAlpha; double tanBeta; if (Utils.AbsCosTheta(wi) > Utils.AbsCosTheta(wo)) { sinAlpha = sinThetaO; tanBeta = sinThetaI / Utils.AbsCosTheta(wi); } else { sinAlpha = sinThetaI; tanBeta = sinThetaO / Utils.AbsCosTheta(wo); } double maxCos = 0; if (sinThetaI > 1e-4 && sinThetaO > 1e-4) { double dCos = Utils.CosPhi(wi) * Utils.CosPhi(wo) + Utils.SinPhi(wi) * Utils.SinPhi(wo); maxCos = Math.Max(0, dCos); } Spectrum nnn = (kd / Math.PI) * (a + b * maxCos * sinAlpha * tanBeta); return(nnn); }
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] }))); }
public override Spectrum f(Vector3 wo, Vector3 wi) { // var phiWi = Phi(wi.x, wi.y); // var phiWo = Phi(wo.x, wo.y); // var thetaWi = Theta(wi.x, wi.y, wi.z); // var thetaWo = Theta(wo.x, wo.y, wo.z); // // var alpha = Math.Max(thetaWi, thetaWo); // var beta = Math.Min(thetaWi, thetaWo); // // return kd * Utils.PiInv * (a + b * Math.Max(0, Math.Cos(phiWi - phiWo))) * Math.Sin(alpha) * Math.Tan(beta); var sinThetaI = Utils.SinTheta(wi); var sinThetaO = Utils.SinTheta(wo); var maxCos = 0.0; if (sinThetaI > 1e-4 && sinThetaO > 1e-4) { var sinPhiI = Utils.SinPhi(wi); var cosPhiI = Utils.CosPhi(wi); var sinPhiO = Utils.SinPhi(wo); var cosPhiO = Utils.CosPhi(wo); var dCos = cosPhiI * cosPhiO + sinPhiI * sinPhiO; maxCos = Math.Max(0, dCos); } double sinAlpha; double tanBeta; if (Utils.AbsCosTheta(wi) > Utils.AbsCosTheta(wo)) { sinAlpha = sinThetaO; tanBeta = sinThetaI / Utils.AbsCosTheta(wi); } else { sinAlpha = sinThetaI; tanBeta = sinThetaO / Utils.AbsCosTheta(wo); } return(kd * Utils.PiInv * (a + b * maxCos * sinAlpha * tanBeta)); }