$$
\newcommand{\nv}{\mathbf{n}}
\newcommand{\lv}{\mathbf{l}}
\newcommand{\vv}{\mathbf{v}}
\newcommand{\hv}{\mathbf{h}}
\newcommand{\mv}{\mathbf{m}}
\newcommand{\rv}{\mathbf{r}}
\newcommand{\ndotl}{\nv\cdot\lv}
\newcommand{\ndotv}{\nv\cdot\vv}
\newcommand{\ndoth}{\nv\cdot\hv}
\newcommand{\ndotm}{\nv\cdot\mv}
\newcommand{\vdoth}{\vv\cdot\hv}
$$
While I worked on our

new shading model for UE4 I tried many different options for our specular BRDF. Specifically, I tried many different terms for to Cook-Torrance microfacet specular BRDF:
$$
f(\lv, \vv) = \frac{D(\hv) F(\vv, \hv) G(\lv, \vv, \hv)}{4(\ndotl)(\ndotv)}
$$
Directly comparing different terms requires being able to swap them while still using the same input parameters. I thought it might be a useful reference to put these all in one place using the same symbols and same inputs. I will use the same form as Naty [1], so please look there for background and theory. I'd like to keep this as a living reference so if you have useful additions or suggestions let me know.

First let me define alpha that will be used for all following equations using UE4's roughness:
$$
\alpha = roughness^2
$$

##
Normal Distribution Function (NDF)

The NDF, also known as the specular distribution, describes the distribution of microfacets for the surface. It is normalized [12] such that:
$$
\int_\Omega D(\mv) (\ndotm) d\omega_i = 1
$$
It is interesting to notice all models have $\frac{1}{\pi \alpha^2}$ for the normalization factor in the isotropic case.

**Blinn-Phong [2]:**
$$
D_{Blinn}(\mv) = \frac{1}{ \pi \alpha^2 } (\ndotm)^{ \left( \frac{2}{ \alpha^2 } - 2 \right) }
$$
This is not the common form but follows when $power = \frac{2}{ \alpha^2 } - 2$.

**Beckmann [3]:**
$$
D_{Beckmann}(\mv) = \frac{1}{ \pi \alpha^2 (\ndotm)^4 } \exp{ \left( \frac{(\ndotm)^2 - 1}{\alpha^2 (\ndotm)^2} \right) }
$$

**GGX (Trowbridge-Reitz) [4]:**
$$
D_{GGX}(\mv) = \frac{\alpha^2}{\pi((\ndotm)^2 (\alpha^2 - 1) + 1)^2}
$$

**GGX Anisotropic [5]:**
$$
D_{GGXaniso}(\mv) = \frac{1}{\pi \alpha_x \alpha_y} \frac{1}{ \left( \frac{(\mathbf{x} \cdot \mv)^2}{\alpha_x^2} + \frac{(\mathbf{y} \cdot \mv)^2}{\alpha_y^2} + (\ndotm)^2 \right)^2 }
$$

##
Geometric Shadowing

The geometric shadowing term describes the shadowing from the microfacets. This means ideally it should depend on roughness and the microfacet distribution.

**Implicit [1]:**
$$
G_{Implicit}(\lv,\vv,\hv) = (\ndotl)(\ndotv)
$$

**Neumann [6]:**
$$
G_{Neumann}(\lv,\vv,\hv) = \frac{ (\ndotl)(\ndotv) }{ \mathrm{max}( \ndotl, \ndotv ) }
$$

**Cook-Torrance [11]:**
$$
G_{Cook-Torrance}(\lv,\vv,\hv) = \mathrm{min}\left( 1, \frac{ 2(\ndoth)(\ndotv) }{\vdoth}, \frac{ 2(\ndoth)(\ndotl) }{\vdoth} \right)
$$

**Kelemen [7]:**
$$
G_{Kelemen}(\lv,\vv,\hv) = \frac{ (\ndotl)(\ndotv) }{ (\vdoth)^2 }
$$

###
Smith

The following geometric shadowing models use Smith's method[8] for their respective NDF. Smith breaks $G$ into two components: light and view, and uses the same equation for both:
$$
G(\lv, \vv, \hv) = G_{1}(\lv) G_{1}(\vv)
$$
I will define $G_1$ below for each model and skip duplicating the above equation.

**Beckmann [4]:**
$$
c = \frac{\ndotv}{ \alpha \sqrt{1 - (\ndotv)^2} }
$$
$$
G_{Beckmann}(\vv) = \left\{
\begin{array}{l l}
\frac{ 3.535 c + 2.181 c^2 }{ 1 + 2.276 c + 2.577 c^2 } & \quad \text{if $c < 1.6$}\\
1 & \quad \text{if $c \geq 1.6$}
\end{array} \right.
$$

**Blinn-Phong:**
The Smith integral has no closed form solution for Blinn-Phong. Walter [4] suggests using the same equation as Beckmann.

**GGX [4]:**
$$
G_{GGX}(\vv) = \frac{ 2 (\ndotv) }{ (\ndotv) + \sqrt{ \alpha^2 + (1 - \alpha^2)(\ndotv)^2 } }
$$
This is not the common form but is a simple refactor by multiplying by $\frac{\ndotv}{\ndotv}$.

**Schlick-Beckmann:**
Schlick [9] approximated the Smith equation for Beckmann. Naty [1] warns that Schlick approximated the wrong version of Smith, so be sure to compare to the Smith version before using.
$$
k = \alpha \sqrt{ \frac{2}{\pi} }
$$
$$
G_{Schlick}(\vv) = \frac{\ndotv}{(\ndotv)(1 - k) + k }
$$

**Schlick-GGX:**
For UE4, I used the Schlick approximation and matched it to the GGX Smith formulation by remapping $k$ [10]:
$$
k = \frac{\alpha}{2}
$$

##
Fresnel

The Fresnel function describes the amount of light that reflects from a mirror surface given its index of refraction. Instead of using IOR we instead use the parameter or $F_0$ which is the reflectance at normal incidence.

**None:**
$$
F_{None}(\mathbf{v}, \mathbf{h}) = F_0
$$

**Schlick [9]:**
$$
F_{Schlick}(\mathbf{v}, \mathbf{h}) = F_0 + (1 - F_0) ( 1 - (\vdoth) )^5
$$

**Cook-Torrance [11]:**
$$
\eta = \frac{ 1 + \sqrt{F_0} }{ 1 - \sqrt{F_0} }
$$
$$
c = \vdoth
$$
$$
g = \sqrt{ \eta^2 + c^2 - 1 }
$$
$$
F_{Cook-Torrance}(\mathbf{v}, \mathbf{h}) = \frac{1}{2} \left( \frac{g - c}{g + c} \right)^2
\left( 1 + \left( \frac{ (g + c)c - 1 }{ (g - c)c+ 1 } \right)^2 \right)
$$

##
Optimize

Be sure to optimize the BRDF shader code as a whole. I choose these forms of the equations to either match the literature or to demonstrate some property. They are not in the optimal form to compute in a pixel shader. For example, grouping Smith GGX with the BRDF denominator we have this:
$$
\frac{ G_{GGX}(\lv) G_{GGX}(\vv) }{4(\ndotl)(\ndotv)}
$$
In optimized HLSL it looks like this:

float a2 = a*a;

float G_V = NoV + sqrt( (NoV - NoV * a2) * NoV + a2 );

float G_L = NoL + sqrt( (NoL - NoL * a2) * NoL + a2 );

return rcp( G_V * G_L );

If you are using this on an older non-scalar GPU you could vectorize it as well.

###
References

[1] Hoffman 2013,

"Background: Physics and Math of Shading"
[2] Blinn 1977, "Models of light reflection for computer synthesized pictures"

[3] Beckmann 1963, "The scattering of electromagnetic waves from rough surfaces"

[4] Walter et al. 2007,

"Microfacet models for refraction through rough surfaces"
[5] Burley 2012,

"Physically-Based Shading at Disney"
[6] Neumann et al. 1999,

"Compact metallic reflectance models"
[7] Kelemen 2001,

"A microfacet based coupled specular-matte brdf model with importance sampling"
[8] Smith 1967, "Geometrical shadowing of a random rough surface"

[9] Schlick 1994,

"An Inexpensive BRDF Model for Physically-Based Rendering"
[10] Karis 2013,

"Real Shading in Unreal Engine 4"
[11] Cook and Torrance 1982,

"A Reflectance Model for Computer Graphics"
[12] Reed 2013,

"How Is the NDF Really Defined?"