Book1.11.4 Unclear Argument Passing in Schlick's Approximation for Fresnel Reflection
The issue is related to the reflectance function in the dielectric class (material.h, line 86).
Schlick’s approximation for Fresnel reflection is given by:
$$ R(\theta_i) = R_0 + (1 - R_0)(1 - \cos\theta_i)^5 $$
where:
$$ R_0 = \left(\frac{\eta_i - \eta_t}{\eta_i + \eta_t}\right)^2 = \left(\frac{1 - \eta_t / \eta_i}{1 + \eta_t / \eta_i}\right)^2 $$
Here, the refractive index transitions from $\eta_i$ to $\eta_t$.
In the implementation, the variable ri represents etai_over_etat, or $\eta_i / \eta_t$. Given this, the function should ideally be called as reflectance(cos_theta, 1 / ri) rather than reflectance(cos_theta, ri). However, because of the squared term in the formula:
$$ R_0 = \left(\frac{\eta_i - \eta_t}{\eta_i + \eta_t}\right)^2 = \left(\frac{\eta_i / \eta_t - 1}{\eta_i / \eta_t + 1}\right)^2 = \left(\frac{1 - \eta_i / \eta_t}{\eta_i / \eta_t + 1}\right)^2 $$
the original implementation reflectance(cos_theta, ri) also produces the correct result.
That said, this implementation might be confusing for beginners (I must admit, I initially misinterpreted it myself XD). Since the book does not explicitly include the Fresnel reflection equation or Schlick’s approximation, it would be helpful to provide a brief introduction beforehand. Alternatively, the implementation could be made clearer by explicitly passing both refractive indices, like this:
// Usage
reflectance(cos_theta_i, ri, 1.0);
// Function
static double reflectance(double cos_theta_i, double eta_i, double eta_t) {
double r0 = (eta_i - eta_t) / (eta_i + eta_t);
r0 *= r0;
return r0 + (1 - r0) * std::pow(1 - cos_theta_i, 5);
}
Also, I think it would be more helpful to briefly introduce the formulas for Fresnel reflection coefficients $R_s$ and $R_p$, and then explain that $R_0$ is an approximation taken at normal incidence.