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)); }