Spectrum sample(BSDFQueryRecord &bRec, const Point2 &sample) const {
		bool sampleReflection   = (bRec.typeMask & EDeltaReflection)
				&& (bRec.component == -1 || bRec.component == 0);
		
		if (!sampleReflection || Frame::cosTheta(bRec.wi) <= 0)
			return Spectrum(0.0f);

		bRec.sampledComponent = 0;
		bRec.sampledType = EDeltaReflection;
		bRec.wo = reflect(bRec.wi);

		return m_specularReflectance->getValue(bRec.its) *
			fresnelConductor(Frame::cosTheta(bRec.wi), m_eta, m_k);
	}
	Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
		bool sampleReflection   = (bRec.typeMask & EDeltaReflection)
				&& (bRec.component == -1 || bRec.component == 0);

		/* Verify that the provided direction pair matches an ideal
		   specular reflection; tolerate some roundoff errors */
		if (!sampleReflection || measure != EDiscrete ||
			Frame::cosTheta(bRec.wi) <= 0 ||
			Frame::cosTheta(bRec.wo) <= 0 ||
			std::abs(1 - dot(reflect(bRec.wi), bRec.wo)) > Epsilon)
			return Spectrum(0.0f);

		return m_specularReflectance->getValue(bRec.its) *
			fresnelConductor(Frame::cosTheta(bRec.wi), m_eta, m_k);
	}
Beispiel #3
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));
    }
}
Beispiel #4
0
 LDEVICE float3 F( float cos_theta )
 { return fresnelConductor( cos_theta, m_eta, m_k ); }