~/imallett (Ian Mallett)

Energy-Conserving Blinn-Phong Specular

For BRDFs in graphics, we typically ignore energy conservation, in favor of energy normalization (that is, energy is lost, but at least it isn't gained). Most people are satisfied with that because it models the shadowing and masking effects in microfacet theory. Unfortunately, it completely ignores multiple scattering. The correct answer, then, is somewhere in-between the extremely lossy models typically used and an idealized model that loses none.

This page is my attempt to derive such an idealized model for the Blinn-Phong specular BRDF. I do not succeed. To the first person who can solve the final integral (even just the inner one, as this would make numerically integrating the outer one easier) in closed-form (no sums/integrals/etc.) in terms of elementary functions (sin/cos/etc., no hypergeometric operators/etc., although constants are okay), I will send $50. The same bounty given if the correct answer to the entire problem is obtained a different way.

The (scalar variant of the) Blinn-Phong specular BRDF (at a point \(\vec{x}\) with normal \(\vec{N}\), and with energy-conservation factor \(\alpha\) and specular exponent \(n\)) is:

\[ f_r(\vec{\omega}_i,\vec{\omega}_o) ~:=~ \alpha (\vec{H} \cdot \vec{N})^n = \alpha \left( \frac{ \vec{\omega}_i + \vec{\omega}_o }{ \left \| \vec{\omega}_i + \vec{\omega}_o \right \| }\cdot\vec{N} \right)^n \]

We want to solve for \(\alpha\).

First, energy-conservation means the following:

\[ \int_{\Omega_{\vec{N}}} f_r(\vec{\omega}_i,\vec{\omega}_o) \left( \vec{N} \cdot \vec{\omega}_i \right) d \vec{\omega}_i = 1 \]

We can now substitute in and rearrange:

\[ \int_{\Omega_{\vec{N}}} \alpha (\vec{H} \cdot \vec{N})^n \left( \vec{N} \cdot \vec{\omega}_i \right) d \vec{\omega}_i = 1\\ \int_{\Omega_{\vec{N}}} \left( \frac{ \vec{\omega}_i + \vec{\omega}_o }{ \left \| \vec{\omega}_i + \vec{\omega}_o \right \| }\cdot\vec{N} \right)^n \left( \vec{N} \cdot \vec{\omega}_i \right) d \vec{\omega}_i = \frac{1}{\alpha} \]

To compute \(\left \| \vec{\omega}_i + \vec{\omega}_o \right \|\) is actually surprisingly simple. We can consider both vectors to lie in a plane, separated by angle \(\gamma\). Without loss of generality, for purposes of computing the length, we can move to 2D: suppose \(\vec{\omega}_o:=<0,1>\) and \(\vec{\omega}_i:=<\sin(\gamma),\cos(\gamma)>\). Their sum is \(<\sin(\gamma),1+\cos(\gamma)>\) and the length of that sum is (Pythagorean theorem):

\[ \left \| \vec{\omega}_i + \vec{\omega}_o \right \| = \sqrt{ \sin^2(\gamma) + (1+\cos(\gamma))^2 } = \sqrt{ 2 + 2 \cos(\gamma)} = 2 \cos \left(\frac{\gamma}{2}\right) \]

Since \(\gamma\) is just \(\arccos(\vec{\omega}_i \cdot \vec{\omega}_o)\), we have:

\[ \left \| \vec{\omega}_i + \vec{\omega}_o \right \| = 2 \cos \left(\frac{\gamma}{2}\right) = 2 \cos \left(\frac{1}{2} \arccos(\vec{\omega}_i \cdot \vec{\omega}_o) \right) = 2 \sqrt{\frac{\vec{\omega}_i \cdot \vec{\omega}_o + 1}{2}} = \sqrt{2} \sqrt{\vec{\omega}_i \cdot \vec{\omega}_o + 1} \]

Substitute this into the integral:

\[ \frac{1}{\alpha} = \int_{\Omega_{\vec{N}}} \left( \frac{ \vec{\omega}_i + \vec{\omega}_o }{ \sqrt{2} \sqrt{\vec{\omega}_i \cdot \vec{\omega}_o + 1} }\cdot\vec{N} \right)^n \left( \vec{N} \cdot \vec{\omega}_i \right) d \vec{\omega}_i \]

At this point, you have the basic formulas. Now it's time to try to solve them.

The attempt I pushed most on uses spherical coordinates. First, (re-)define \(\vec{\omega}_o\) and \(\vec{\omega}_i\) in spherical coordinates:

\[ \vec{\omega}_o = \begin{bmatrix} x_o = \sqrt{1-y_o^2}\\ y_o = \vec{N} \cdot \vec{\omega}_o\\ 0 \end{bmatrix},~~~~ \vec{\omega}_i = \begin{bmatrix} \cos(\Delta\theta)~\cdot &\!\!\!\!\! \cos(\phi)\\ &\!\!\!\!\! \sin(\phi)\\ \sin(\Delta\theta)~\cdot &\!\!\!\!\! \cos(\phi) \end{bmatrix} \]

Convert to spherical coordinates, substitute in, and simplify:

\begin{align*} \frac{1}{\alpha} &= \int_0^{\pi/2}\int_0^{2\pi} \left( \frac{ \vec{\omega}_i + \vec{\omega}_o }{ \sqrt{2} \sqrt{\vec{\omega}_i \cdot \vec{\omega}_o + 1} }\cdot\vec{N} \right)^n \left( \vec{N} \cdot \vec{\omega}_i \right) \cdot \cos(\phi) \cdot d \Delta\theta \cdot d \phi \\ &= \int_0^{\pi/2}\int_0^{2\pi} \left( \frac{ \cos(\phi) + y_o }{ \sqrt{2} \sqrt{\smash[b]{ \cos(\Delta\theta)\underbrace{\cos(\phi)\sqrt{1-y_o^2}}_A + \sin(\phi) y_o + 1 }} } \right)^n \cos^2(\phi) \cdot d \Delta\theta \cdot d \phi \\[14pt] &= \int_0^{\pi/2} \cos^2(\phi) \int_0^{2\pi} \left( \frac{ \cos(\phi) + y_o }{ \sqrt{2 A} \sqrt{\smash[b]{ \cos(\Delta\theta) + \underbrace{\frac{\sin(\phi) y_o + 1}{A}}_B }} } \right)^n \cdot d \Delta\theta \cdot d \phi \\[14pt] &= \int_0^{\pi/2} \left(\frac{\cos(\phi)+y_o}{\sqrt{2 A}}\right)^n \cos^2(\phi) \int_0^{2\pi}\left( \cos(\Delta\theta) + B \right)^{-n/2} \cdot d \Delta\theta \cdot d \phi \end{align*}

The inner integral here is surprisingly difficult, even if you assume \(n/2\) is an integer. If you can solve this integral, you get the prize mentioned above!

Ian Mallett - Contact -
- 2021 - Creative Commons License