Spectrum KajiyaKay::f(const Vector3f &wo, const Vector3f &wi) const { Spectrum diffuse(0.f), specular(0.f); if (!Ks.IsBlack()) { // Compute specular Kajiya-Kay term Vector3f wh = wi + wo; if (!(wh.x == 0 && wh.y == 0 && wh.z == 0)) { wh = Normalize(wh); #if 0 Float cosThetaH = Dot(wo, wh); Float sinThetaH = std::sqrt(std::max((Float)0, (Float)1 - cosThetaH * cosThetaH)); Float cosThetaO = CosTheta(wo), sinThetaO = SinTheta(wo); Float spec = std::pow(cosThetao * cosThetah + sinThetaO * sinThetaH, exponent); #else Float tdoth = wh.x; Float spec = std::pow( std::sqrt(std::max((Float)0, (Float)1 - tdoth * tdoth)), exponent); #endif specular = spec * Ks; } } // Compute diffuse Kajiya-Kay term diffuse = Kd * std::sqrt(std::max((Float)0., (Float)1. - wi.x * wi.x)); return (InvPi / AbsCosTheta(wi)) * (diffuse + specular); }
// commented, dpl 10 august 2005 Spectrum OrenNayar::f(const Vector &wo, const Vector &wi) const { float sinthetai = SinTheta(wi); float sinthetao = SinTheta(wo); // Compute cosine term of Oren--Nayar model float sinphii = SinPhi(wi), cosphii = CosPhi(wi); float sinphio = SinPhi(wo), cosphio = CosPhi(wo); float dcos = cosphii * cosphio + sinphii * sinphio; float maxcos = max(0.f, dcos); // Compute sine and tangent terms of Oren--Nayar model float sinalpha, tanbeta; if (fabsf(CosTheta(wi)) > fabsf(CosTheta(wo))) { sinalpha = sinthetao; tanbeta = sinthetai / fabsf(CosTheta(wi)); } else { sinalpha = sinthetai; tanbeta = sinthetao / fabsf(CosTheta(wo)); } return R * INV_PI * (A + B * maxcos * sinalpha * tanbeta); }
Spectrum OrenNayar::f(const Vector3f &wo, const Vector3f &wi) const { Float sinThetaI = SinTheta(wi); Float sinThetaO = SinTheta(wo); // Compute cosine term of Oren-Nayar model Float maxCos = 0; if (sinThetaI > 1e-4 && sinThetaO > 1e-4) { Float sinPhiI = SinPhi(wi), cosPhiI = CosPhi(wi); Float sinPhiO = SinPhi(wo), cosPhiO = CosPhi(wo); Float dCos = cosPhiI * cosPhiO + sinPhiI * sinPhiO; maxCos = std::max((Float)0, dCos); } // Compute sine and tangent terms of Oren-Nayar model Float sinAlpha, tanBeta; if (AbsCosTheta(wi) > AbsCosTheta(wo)) { sinAlpha = sinThetaO; tanBeta = sinThetaI / AbsCosTheta(wi); } else { sinAlpha = sinThetaI; tanBeta = sinThetaO / AbsCosTheta(wo); } return R * InvPi * (A + B * maxCos * sinAlpha * tanBeta); }
inline typename scalar_type<V>::type SinPhi(const V &w) { return w.y() / SinTheta(w); }