Exemple #1
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);
}
// commented, dpl 10 august 2005
Spectrum SpecularTransmission::Sample_f(const Vector &wo,
		Vector *wi, float u1, float u2, float *pdf) const {
	// Figure out which $\eta$ is incident and which is transmitted
	bool entering = CosTheta(wo) > 0.;
	float ei = etai, et = etat;
	if (!entering)
		swap(ei, et);
	// Compute transmitted ray direction
	float sini2 = SinTheta2(wo);
	float eta = ei / et;
	float sint2 = eta * eta * sini2;
	// Handle total internal reflection for transmission
	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;
	Spectrum F = fresnel.Evaluate(CosTheta(wo));
	return (ei*ei)/(et*et) * (Spectrum(1.)-F) * T /
		fabsf(CosTheta(*wi));
}