8.5 Fresnel Incidence Effects

Many BRDF models in graphics do not account for the fact that Fresnel reflection reduces the amount of light that reaches the bottom level of layered objects. Consider a polished wood table or a wall with glossy paint: if you look at their surfaces head-on, you primarily see the wood or the paint pigment color. As you move your viewpoint toward a glancing angle, you see less of the underlying color as it is overwhelmed by increasing glossy reflection due to Fresnel effects.

In this section, we will implement a BRDF model developed by Ashikhmin and Shirley (2000, 2002) that models a diffuse underlying surface with a glossy specular surface above it. The effect of reflection from the diffuse surface is modulated by the amount of energy left after Fresnel effects have been considered. Figure 8.23 shows this idea: when the incident direction is close to the normal, most light is transmitted to the diffuse layer and the diffuse term dominates. When the incident direction is close to glancing, glossy reflection is the primary mode of reflection. The car model in Figure 12.19 uses this BRDF for its paint.

<<BxDF Declarations>>+=  
class FresnelBlend : public BxDF { public: <<FresnelBlend Public Methods>> 
FresnelBlend(const Spectrum &Rd, const Spectrum &Rs, MicrofacetDistribution *distrib); Spectrum f(const Vector3f &wo, const Vector3f &wi) const; Spectrum SchlickFresnel(Float cosTheta) const { auto pow5 = [](Float v) { return (v * v) * (v * v) * v; }; return Rs + pow5(1 - cosTheta) * (Spectrum(1.) - Rs); } Spectrum Sample_f(const Vector3f &wi, Vector3f *sampled_f, const Point2f &u, Float *pdf, BxDFType *sampledType) const; Float Pdf(const Vector3f &wi, const Vector3f &wo) const;
private: <<FresnelBlend Private Data>> 
const Spectrum Rd, Rs; MicrofacetDistribution *distribution;
};

Figure 8.23: The FresnelBlend BRDF models the effect of a surface with a glossy layer on top of a diffuse substrate. As the angle of incidence of the vectors omega Subscript normal i and omega Subscript normal o heads toward glancing (right), the amount of light that reaches the diffuse substrate is reduced by Fresnel effects, and the diffuse layer becomes less visibly apparent.

The model takes two spectra, representing diffuse and specular reflectance, and a microfacet distribution for the glossy layer.

<<BxDF Method Definitions>>+=  
FresnelBlend::FresnelBlend(const Spectrum &Rd, const Spectrum &Rs, MicrofacetDistribution *distribution) : BxDF(BxDFType(BSDF_REFLECTION | BSDF_GLOSSY)), Rd(Rd), Rs(Rs), distribution(distribution) { }

<<FresnelBlend Private Data>>= 
const Spectrum Rd, Rs; MicrofacetDistribution *distribution;

This model is based on the weighted sum of a glossy specular term and a diffuse term. Accounting for reciprocity and energy conservation, the glossy specular term is derived as

f Subscript normal r Baseline left-parenthesis normal p Subscript Baseline comma omega Subscript normal o Baseline comma omega Subscript normal i Baseline right-parenthesis equals StartFraction upper D left-parenthesis omega Subscript normal h Baseline right-parenthesis upper F left-parenthesis omega Subscript normal o Baseline right-parenthesis Over 4 left-parenthesis omega Subscript normal h Baseline dot omega Subscript normal i Baseline right-parenthesis left-parenthesis max left-parenthesis left-parenthesis bold n Subscript Baseline dot omega Subscript normal o Baseline right-parenthesis comma left-parenthesis bold n Subscript Baseline dot omega Subscript normal i Baseline right-parenthesis right-parenthesis right-parenthesis EndFraction comma

where upper D left-parenthesis omega Subscript normal h Baseline right-parenthesis is a microfacet distribution term and upper F left-parenthesis omega Subscript normal o Baseline right-parenthesis represents Fresnel reflectance. Note that this is quite similar to the Torrance–Sparrow model.

The key to Ashikhmin and Shirley’s model is the derivation of a diffuse term such that the model still obeys reciprocity and conserves energy. The derivation is dependent on an approximation to the Fresnel reflection equations due to Schlick (1993), who approximated Fresnel reflection as

upper F Subscript normal r Baseline left-parenthesis cosine theta right-parenthesis equals upper R plus left-parenthesis 1 minus upper R right-parenthesis left-parenthesis 1 minus cosine theta right-parenthesis Superscript 5 Baseline comma

where upper R is the reflectance of the surface at normal incidence.

Given this Fresnel term, the diffuse term in the following equation successfully models Fresnel-based reduced diffuse reflection in a physically plausible manner:

f Subscript normal r Baseline left-parenthesis normal p Subscript Baseline comma omega Subscript normal i Baseline comma omega Subscript normal o Baseline right-parenthesis equals StartFraction 28 upper R Subscript normal d Baseline Over 23 pi EndFraction left-parenthesis 1 minus upper R Subscript normal s Baseline right-parenthesis left-parenthesis 1 minus left-parenthesis 1 minus StartFraction left-parenthesis bold n Subscript Baseline dot omega Subscript normal i Baseline right-parenthesis Over 2 EndFraction right-parenthesis Superscript 5 Baseline right-parenthesis left-parenthesis 1 minus left-parenthesis 1 minus StartFraction left-parenthesis bold n Subscript Baseline dot omega Subscript normal o Baseline right-parenthesis Over 2 EndFraction right-parenthesis Superscript 5 Baseline right-parenthesis period

We will not include the derivation of this result here.

<<FresnelBlend Public Methods>>= 
Spectrum SchlickFresnel(Float cosTheta) const { auto pow5 = [](Float v) { return (v * v) * (v * v) * v; }; return Rs + pow5(1 - cosTheta) * (Spectrum(1.) - Rs); }

<<BxDF Method Definitions>>+=  
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; }