LDEVICE float BeckmannDistribution::G( float3 N, float3 H, float3 w_in, float3 w_out ) const { return smithG1( N, H, w_in ) * smithG1( N, H, w_out ); }
Float microfacet(Float mu_o, Float mu_i, std::complex<Float> eta_, Float alpha, Float phi_d) { Float sinThetaI = math::safe_sqrt(1-mu_i*mu_i), sinThetaO = math::safe_sqrt(1-mu_o*mu_o), cosPhi = std::cos(phi_d), sinPhi = std::sin(phi_d); Vector wi(-sinThetaI, 0, -mu_i); Vector wo(sinThetaO*cosPhi, sinThetaO*sinPhi, mu_o); bool reflect = -mu_i*mu_o > 0; if (mu_o == 0 || mu_i == 0) return 0.f; bool conductor = eta_.imag() != 0.0f; if (conductor && !reflect) return 0.0f; std::complex<Float> eta = (-mu_i > 0 || conductor) ? eta_ : std::complex<Float>(1) / eta_; Vector H = (wi + wo * (reflect ? 1.0f : eta.real())).normalized(); H *= math::signum(Frame::cosTheta(H)); Float cosThetaH2 = Frame::cosTheta2(H), exponent = -Frame::tanTheta2(H) / (alpha*alpha), D = std::exp(exponent) / (math::Pi * alpha*alpha * cosThetaH2*cosThetaH2), F = !conductor ? fresnelDielectric(wi.dot(H), eta_.real()) : fresnelConductor(std::abs(wi.dot(H)), eta), G = smithG1(wi, H, alpha) * smithG1(wo, H, alpha); if (reflect) { return F * D * G / (4.0f * std::abs(mu_i*mu_o)); } else { Float sqrtDenom = wi.dot(H) + eta.real() * wo.dot(H); return std::abs(((1 - F) * D * G * eta.real() * eta.real() * wi.dot(H) * wo.dot(H)) / (mu_i*mu_o * sqrtDenom * sqrtDenom)); } }