static Vector3f TrowbridgeReitzSample(const Vector3f &wi, Float alpha_x, Float alpha_y, Float U1, Float U2) { // 1. stretch wi Vector3f wiStretched = Normalize(Vector3f(alpha_x * wi.x, alpha_y * wi.y, wi.z)); // 2. simulate P22_{wi}(x_slope, y_slope, 1, 1) Float slope_x, slope_y; TrowbridgeReitzSample11(CosTheta(wiStretched), U1, U2, &slope_x, &slope_y); // 3. rotate Float tmp = CosPhi(wiStretched) * slope_x - SinPhi(wiStretched) * slope_y; slope_y = SinPhi(wiStretched) * slope_x + CosPhi(wiStretched) * slope_y; slope_x = tmp; // 4. unstretch slope_x = alpha_x * slope_x; slope_y = alpha_y * slope_y; // 5. compute normal return Normalize(Vector3f(-slope_x, -slope_y, 1.)); }
// 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); }