Exemple #1
0
Float MicrofacetDistribution::Pdf(const Vector3f &wo,
                                  const Vector3f &wh) const {
    if (sampleVisibleArea)
        return D(wh) * G1(wo) * AbsDot(wo, wh) / AbsCosTheta(wo);
    else
        return D(wh) * AbsCosTheta(wh);
}
Exemple #2
0
Spectrum FresnelSpecular::Sample_f(const Vector3f &wo, Vector3f *wi,
                                   const Point2f &u, Float *pdf,
                                   BxDFType *sampledType) const {
    Float F = FrDielectric(CosTheta(wo), etaA, etaB);
    if (u[0] < F) {
        // Compute specular reflection for _FresnelSpecular_

        // Compute perfect specular reflection direction
        *wi = Vector3f(-wo.x, -wo.y, wo.z);
        if (sampledType)
            *sampledType = BxDFType(BSDF_SPECULAR | BSDF_REFLECTION);
        *pdf = F;
        return F * R / AbsCosTheta(*wi);
    } else {
        // Compute specular transmission for _FresnelSpecular_

        // Figure out which $\eta$ is incident and which is transmitted
        bool entering = CosTheta(wo) > 0;
        Float etaI = entering ? etaA : etaB;
        Float etaT = entering ? etaB : etaA;

        // Compute ray direction for specular transmission
        if (!Refract(wo, Faceforward(Normal3f(0, 0, 1), wo), etaI / etaT, wi))
            return 0;
        Spectrum ft = T * (1 - F);

        // Account for non-symmetry with transmission to different medium
        if (mode == TransportMode::Radiance)
            ft *= (etaI * etaI) / (etaT * etaT);
        if (sampledType)
            *sampledType = BxDFType(BSDF_SPECULAR | BSDF_TRANSMISSION);
        *pdf = 1 - F;
        return ft / AbsCosTheta(*wi);
    }
}
Exemple #3
0
float Microfacet::G(const Vector &wo, const Vector &wi,
		const Vector &wh) const {
	float NdotWh = AbsCosTheta(wh); //半角和法线之间的cos值  相当于是点乘
	float NdotWo = AbsCosTheta(wo); //出射方向与法线
	float NdotWi = AbsCosTheta(wi); //入射方向与法线
	float WodotWh = AbsDot(wh, wo); //出射和半角向量之间的点乘
	return min(1.0f,
			min((2.f * NdotWh * NdotWo / WodotWh),
					(2.f * NdotWh * NdotWi / WodotWh)));
}
Exemple #4
0
Spectrum MicrofacetReflection::f(const Vector3f &wo, const Vector3f &wi) const {
    Float cosThetaO = AbsCosTheta(wo), cosThetaI = AbsCosTheta(wi);
    Vector3f wh = wi + wo;
    // Handle degenerate cases for microfacet reflection
    if (cosThetaI == 0 || cosThetaO == 0) return Spectrum(0.);
    if (wh.x == 0 && wh.y == 0 && wh.z == 0) return Spectrum(0.);
    wh = Normalize(wh);
    Spectrum F = fresnel->Evaluate(Dot(wi, wh));
    return R * distribution->D(wh) * distribution->G(wo, wi) * F /
           (4 * cosThetaI * cosThetaO);
}
Exemple #5
0
	RGBColour BxDF::Rho(int p_nSamples, const float* p_samples1, const float* p_samples2) const{
		RGBColour r = 0.;
		for (int i = 0; i < p_nSamples; ++i){
			/* Estimate one term of p_hd */
			Vector3 wo,wi;
			wo = MonteCarlo::UniformSampleHemisphere(p_samples1[2 * i], p_samples1[2 * i + 1]);
			float pdf_o = Maths::InvPiTwo, pdf_i = 0.f;
			RGBColour f = Sample_F(wo, wi, p_samples2[2 * i], p_samples2[2 * i + 1], pdf_i);
			if (pdf_i > 0.) r += f * AbsCosTheta(wi) * AbsCosTheta(wo) / (pdf_o * pdf_i);
		}
		return r / float(Maths::Pi * p_nSamples);
	}
Exemple #6
0
Spectrum BxDF::rho(int nSamples, const Point2f *u1, const Point2f *u2) const {
    Spectrum r(0.f);
    for (int i = 0; i < nSamples; ++i) {
        // Estimate one term of $\rho_\roman{hh}$
        Vector3f wo, wi;
        wo = UniformSampleHemisphere(u1[i]);
        Float pdfo = UniformHemispherePdf(), pdfi = 0;
        Spectrum f = Sample_f(wo, &wi, u2[i], &pdfi);
        if (pdfi > 0)
            r += f * AbsCosTheta(wi) * AbsCosTheta(wo) / (pdfo * pdfi);
    }
    return r / (Pi * nSamples);
}
Exemple #7
0
Spectrum FresnelBlend::f(const Vector3f &wo, const Vector3f &wi) const {
    auto pow5 = [](Float v) { return (v * v) * (v * v) * v; };
    Spectrum diffuse = (28.f / (23.f * Pi)) * Rd * (Spectrum(1.f) - Rs) *
                       (1 - pow5(1 - .5f * AbsCosTheta(wi))) *
                       (1 - pow5(1 - .5f * AbsCosTheta(wo)));
    Vector3f wh = wi + wo;
    if (wh.x == 0 && wh.y == 0 && wh.z == 0) return Spectrum(0);
    wh = Normalize(wh);
    Spectrum specular =
        distribution->D(wh) /
        (4 * AbsDot(wi, wh) * std::max(AbsCosTheta(wi), AbsCosTheta(wo))) *
        SchlickFresnel(Dot(wi, wh));
    return diffuse + specular;
}
Exemple #8
0
//这里使用的就是Torrance-Sparrow Modle的公式
RGB Microfacet::f(const Vector &wo, const Vector &wi) const {
	float cosO = AbsCosTheta(wo);
	if (cosO == 0)
		return RGB(0);
	float cosI = AbsCosTheta(wi);
	if (cosI == 0)
		return RGB(0);
	Vector wh = wi + wo;
	if (wh.x == 0 && wh.y == 0 && wh.z == 0)
		return RGB(0);
	wh = Normalize(wh);
	float cosH = Dot(wi, wh);
	RGB F = mFresnel->Evaluate(cosH);
	return mR * F * mDistribution->D(wh) * G(wo, wi, wh) / (4.0f * cosO * cosI);
}
struct Spectrum SpecularReflection_cc_Sample_f(struct const_Vector wo, struct Vector *wi, float u1, float u2, float *pdf) {
    // Compute perfect specular reflection direction
    *wi = make_Vector(-wo.x, -wo.y, wo.z);
    *pdf = 1.f;
    struct Spectrum tmp1 = multiply(fresnel_arrow_Evaluate(CosTheta(wo)), make_Spectrum(R));
    return div(tmp1, make_Spectrum(AbsCosTheta(*wi)));
}
Exemple #10
0
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);
}
struct Spectrum SpecularReflection_cc_Sample_f(const_Vector wo, Vector *wi, float u1, float u2, float *pdf) {
//    return 0;// mgr
//    return 1;//mgr
    // Compute perfect specular reflection direction
    *wi = make_Vector(-wo.x, -wo.y, wo.z);
    *pdf = 1.f;
    return make_Spectrum(fresnel__Evaluate(CosTheta(wo)) * R / AbsCosTheta(*wi));
}
Exemple #12
0
Spectrum SpecularReflection::Sample_f(const Vector3f &wo, Vector3f *wi,
                                      const Point2f &sample, Float *pdf,
                                      BxDFType *sampledType) const {
    // Compute perfect specular reflection direction
    *wi = Vector3f(-wo.x, -wo.y, wo.z);
    *pdf = 1;
    return fresnel->Evaluate(CosTheta(*wi)) * R / AbsCosTheta(*wi);
}
Exemple #13
0
Spectrum
Heitz::f(const Vector &woInput, const Vector &wiInput) const
{
    // In PBRT's implementation, woInput and wiInput is not guaranteed to be at the same side of the shading normal
    // We inverse them if woInput is on the other side.
    // Note: because BSDF::f() determines BSDF_REFLECTION and BSDF_TRANSMISSION using ng (geometric normal) instead
	//       of nn (shading normal), it's possible that woInput and wiInput has opposite sign of z-axis. Therefore,
	//       we determine if the shading normal is at the opposite side using woInput (viewing direction) only: we
	//       always make the viewing direction from the +Z side

    Vector wo = woInput, wi = wiInput;
    if (wo.z < 0.f) {
        // Reverse side
        wo = -wo;
        wi = -wi;
    }

    float cosThetaO = CosTheta(wo),
          absCosThetaI = AbsCosTheta(wi);
    Assert(cosThetaO >= 0.f);
    if (cosThetaO < sSmallValue || absCosThetaI < sSmallValue) {
        return Spectrum(0.f);
    }

    Vector wh = wi + wo;
    if (wh.x == 0. && wh.y == 0. && wh.z == 0.) {
        return Spectrum(0.f);
    }
    wh = Normalize(wh);
    float i_dot_h = Dot(wi, wh);
    Spectrum F = fresnel->Evaluate(i_dot_h);

    // Specular/glossy component
    float spec = mDistribution.D(wh) * mDistribution.G(wo, wi, wh) /
            (4.f * cosThetaO * absCosThetaI);

    // Diffuse component
    Spectrum Fdiff = Spectrum(1.f) - fresnel->Evaluate(cosThetaO);
    float diff = wi.z > 0.f ? INV_PI : 0.f;

    // TODO: test
    //F = Spectrum(1.f);

    // Note wi is possible to be at lower hemisphere, so we need to use
    // AbsCosTheta()
    //return R * (F * spec + (Spectrum(1.f) - F) * diff);
    return R * (F * spec + Fdiff * diff);

    // TODO: test
    /*float Dval = mDistribution.D(wh),
          Gval = mDistribution.G(wo, wi, wh);
    Spectrum val = R * Dval * Gval * F /
            (4.f * cosThetaO * absCosThetaI);
    if (isinf(val.y()) || val.y() < -sSmallValue) {
        fprintf(stderr, "invalid value\n");
    }
    return val;*/
}
Exemple #14
0
	float BxDF::PDF(const Vector3& p_wo, const Vector3& p_wi) const {
		bool temp =  SameHemisphere(p_wo, p_wi);
		if (temp){
			return AbsCosTheta(p_wi) * Maths::InvPi;
		}
		
			return 0.0f;
		//return SameHemisphere(p_wo, p_wi) ? AbsCosTheta(p_wi) * Maths::InvPi : 0.f;
	}
Exemple #15
0
	RGBColour BxDF::Rho(const Vector3& p_w, int p_nSamples, const float* p_samples) const{
		RGBColour r = 0.;
		for (int i = 0; i < p_nSamples; ++i){
			/* Estimate one term of p_hd */
			Vector3 wi;
			float pdf = 0.f;
			RGBColour f = Sample_F(p_w, wi, p_samples[2 * i], p_samples[2 * i + 1], pdf);
			if (pdf > 0.) r += f * AbsCosTheta(wi) / pdf;
		}
		return r / float(p_nSamples);
	}
Exemple #16
0
Spectrum BxDF::rho(const Vector3f &w, int nSamples, const Point2f *u) const {
    Spectrum r(0.);
    for (int i = 0; i < nSamples; ++i) {
        // Estimate one term of $\rho_\roman{hd}$
        Vector3f wi;
        Float pdf = 0;
        Spectrum f = Sample_f(w, &wi, u[i], &pdf);
        if (pdf > 0) r += f * AbsCosTheta(wi) / pdf;
    }
    return r / nSamples;
}
Exemple #17
0
float
Heitz::Pdf(const Vector &wo, const Vector &wi) const 
{
    // TODO: for test
    if (mUseUniformSampling) {
        return SameHemisphere(wo, wi) ? AbsCosTheta(wi) * INV_PI : 0.f;

    } else {
        float pdfSpec = 0.f;
        if (wo.z < 0.f) {
            // Reverse side
            pdfSpec = mDistribution.Pdf(-wo, -wi);
        } else {
            pdfSpec = mDistribution.Pdf(wo, wi);
        }

        float pdfDiff = SameHemisphere(wo, wi) ? AbsCosTheta(wi) * INV_PI : 0.f;

        // TODO: what percentage between diffuse and specular? Currently use 50%
        return (pdfDiff + pdfSpec) * 0.5f;
    }
}
Exemple #18
0
//复制自PBRT
float Anisotropic::Pdf(const Vector &wo, const Vector &wi) const {
    Vector wh = Normalize(wo + wi);
    float costhetah = AbsCosTheta(wh);
    float ds = 1.f - costhetah * costhetah;
    float anisotropic_pdf = 0.f;
    if (ds > 0.f && Dot(wo, wh) > 0.f) {
        float e = (ex * wh.x * wh.x + ey * wh.y * wh.y) / ds;
        float d = sqrtf((ex+1.f) * (ey+1.f)) * M_INV_TWO_PI *
                  powf(costhetah, e);
        anisotropic_pdf = d / (4.f * Dot(wo, wh));
    }
    return anisotropic_pdf;
}
Exemple #19
0
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);
}
Exemple #20
0
Spectrum SpecularTransmission::Sample_f(const Vector3f &wo, Vector3f *wi,
                                        const Point2f &sample, Float *pdf,
                                        BxDFType *sampledType) const {
    // Figure out which $\eta$ is incident and which is transmitted
    bool entering = CosTheta(wo) > 0;
    Float etaI = entering ? etaA : etaB;
    Float etaT = entering ? etaB : etaA;

    // Compute ray direction for specular transmission
    if (!Refract(wo, Faceforward(Normal3f(0, 0, 1), wo), etaI / etaT, wi))
        return 0;
    *pdf = 1;
    Spectrum ft = T * (Spectrum(1.) - fresnel.Evaluate(CosTheta(*wi)));
    // Account for non-symmetry with transmission to different medium
    if (mode == TransportMode::Radiance) ft *= (etaI * etaI) / (etaT * etaT);
    return ft / AbsCosTheta(*wi);
}
Exemple #21
0
RGB SpecularTransmission::Sample_f(const Vector& wo, Vector* wi, float u1,
		float u2, float *pdf) const {
	bool entering = CosTheta(wo) > 0.;
	float ei = mEtaI, et = mEtaT;
	if (!entering) //判断wo是从外面射入还是从内部射出
		swap(ei, et);
	//根据Snell's law 计算折射方向
	float sini2 = SinTheta2(wo);
	float eta = ei / et;
	float sint2 = eta * eta * sini2;

	if (sint2 >= 1.)
		return 0.; //所有的光线全部反射,所以没有折射
	float cost = sqrtf(max(0.f, 1.f - sint2));
	if (entering)
		cost = -cost; //设置符号
	float sintOverSini = eta;
	*wi = Vector(sintOverSini * -wo.x, sintOverSini * -wo.y, cost);
	*pdf = 1.f;
	RGB F = mFresnel.Evaluate(CosTheta(wo)); //计算反射系数
	return (ei * ei) / (et * et) * (RGB(1.0f) - F) * mScale / AbsCosTheta(*wi);
}
Exemple #22
0
//复制自PBRT
void Anisotropic::Sample_f(const Vector3f &wo, Vector3f *wi, Float u1, Float u2,
		Float *pdf) const {
	Float phi, costheta;
	if (u1 < .25f) {
		sampleFirstQuadrant(4.f * u1, u2, &phi, &costheta);
	} else if (u1 < .5f) {
		u1 = 4.f * (.5f - u1);
		sampleFirstQuadrant(u1, u2, &phi, &costheta);
		phi = Pi - phi;
	} else if (u1 < .75f) {
		u1 = 4.f * (u1 - .5f);
		sampleFirstQuadrant(u1, u2, &phi, &costheta);
		phi += Pi;
	} else {
		u1 = 4.f * (1.f - u1);
		sampleFirstQuadrant(u1, u2, &phi, &costheta);
		phi = 2.f * Pi - phi;
	}
	Float sintheta = sqrtf(std::max(0.f, 1.f - costheta * costheta));
	Vector3f wh = SphericalDirection(sintheta, costheta, phi);
	if (!SameHemisphere(wo, wh))
		wh = -wh;

	// Compute incident direction by reflecting about $\wh$
	*wi = -wo + 2.f * Dot(wo, wh) * wh;

	// Compute PDF for $\wi$ from anisotropic distribution
	Float costhetah = AbsCosTheta(wh);
	Float ds = 1.f - costhetah * costhetah;
	Float anisotropic_pdf = 0.f;
	if (ds > 0.f && Dot(wo, wh) > 0.f) {
		Float e = (ex * wh.x * wh.x + ey * wh.y * wh.y) / ds;
		Float d = sqrtf((ex + 1.f) * (ey + 1.f)) * InvTwoPi
				* powf(costhetah, e);
		anisotropic_pdf = d / (4.f * Dot(wo, wh));
	}
	*pdf = anisotropic_pdf;
}
Exemple #23
0
Float BxDF::Pdf(const Vector3f &wo, const Vector3f &wi) const {
    return SameHemisphere(wo, wi) ? AbsCosTheta(wi) * InvPi : 0;
}
Exemple #24
0
RGB SpecularReflection::Sample_f(const Vector& wo, Vector* wi, float u1,
		float u2, float *pdf) const {
	*wi = Vector(-wo.x, -wo.y, wo.z);	//反射向量
	*pdf = 1.f;	//概率分布为1
	return mFresnel->Evaluate(CosTheta(wo)) * mScale / AbsCosTheta(*wi); //镜面反射的brdf公式
}
Exemple #25
0
Float LambertianTransmission::Pdf(const Vector3f &wo,
                                  const Vector3f &wi) const {
    return !SameHemisphere(wo, wi) ? AbsCosTheta(wi) * InvPi : 0;
}
Exemple #26
0
Float FresnelBlend::Pdf(const Vector3f &wo, const Vector3f &wi) const {
    if (!SameHemisphere(wo, wi)) return 0;
    Vector3f wh = Normalize(wo + wi);
    Float pdf_wh = distribution->Pdf(wo, wh);
    return .5f * (AbsCosTheta(wi) * InvPi + pdf_wh / (4 * Dot(wo, wh)));
}