Spherical Harmonic Lighting
Spherical Harmonic Lighting: The Gritty Details
Spherical Harmonic Lighting A efficient method for capturing and displaying Global Illumination solutions across the surface of an object.
Background
Light Modeling
For a point \(x\) at the surface, the reflected light intensity from viewing direction $ \mathbf d_0$ is modelled as
where \(S\) is the unit sphere centered at \(x\) and
\(L_e(x, \mathbf d_0)\) is the direct emission light
\(f_r(x, \mathbf d_i - \mathbf d_0)\) is the BRDF term, transforming incoming light $ \mathbf d_i$ to \(\mathbf d_0\)
\(L_r(x,x')\) the the light reflected from \(x'\) to \(x\)
\(G(x, x')\) is the geometric relationship between \(x\) and \(x'\)
Of course, this computation is intractable and we do lots compromises (given up some terms, simplify the model).
Monte Carlo Integration
Known that the expectation is defined as
for any function \(f\), thus if we have that \(f' = f/p\), we have
More over, if we can uniformally sample \(N\) points on the sphere surface, then we have \(p(x_i) = 1/4\pi\) is constant. so that the equation is reduced to summing samples.
Note that uniform sampling from polar coordinate \((\theta\in [0,2\pi), \phi\in[-\pi/2,\pi/2))\) is not a uniform sampling over the sphere, since we are sampling over the circles with different radius \(\sin\phi\).
Instead, we transforms from unit square \((u,v)\)
function sphere_sample(N) {
const positions = new Float32Array(N * 3);
for (let i = 0; i < N; i++) {
// uniform sample from [0, 1) * [0, 1)
const u = Math.random();
const v = Math.random();
// transform to polar
const theta = 2 * PI * u;
const phi = 2 * Math.acos(Math.sqrt(1 - v));
// transform to xyz
positions[3 * i] = Math.cos(theta) * Math.sin(phi);
positions[3 * i + 1] = Math.sin(theta) * Math.sin(phi);
positions[3 * i + 2] = Math.cos(phi);
}
return positions;
}