Beispiel #1
0
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 );
}
Beispiel #2
0
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));
    }
}