Skip to content

Book1.11.4 Unclear Argument Passing in Schlick's Approximation for Fresnel Reflection #1672

@Xlucidator

Description

@Xlucidator

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions