GLSL Programming/Unity/Diffuse Reflection of Skylight

This tutorial covers hemisphere lighting.

It is based on diffuse per-vertex lighting as described in. If you haven't read that tutorial yet, you should read it first.

Hemisphere lighting basically computes diffuse illumination with a huge light source that covers a whole hemisphere around the scene, for example the sky. It often includes the illumination with another hemisphere from below using a different color since the calculation is almost for free. In the photo, the spherical building is illuminated by a overcast sky. However, there is also illumination by the green water basin around it, which results in a noticeable greenish illumination of the lower half of the building.



Hemisphere Lighting
If we assume that each point (in direction L) of a hemisphere around a point on the surface acts as a light source, then we should integrate the diffuse illumination (given by max(0, L·N) as discussed in ) from all the points on the hemisphere by an integral. Let's call the normalized direction of the rotation axis of the hemisphere U (for “up”). If the surface normal N points in the direction of U, we have full illumination with a color specified by the user. If there is an angle γ between them (i.e. cos(γ) = U·N), only a spherical wedge (see the Wikipedia article) of the hemisphere illuminates the surface point. The fraction w of this illumination in comparison to the full illumination is:

$$w = \frac{1}{2}(1 + \cos(\gamma))$$ $$= \frac{1}{2}(1 + \mathbf{U}\cdot\mathbf{N})$$

Thus, we can compute the incoming light as w times the user-specified color of the full illumination by the hemisphere. The hemisphere in the opposite direction will illuminate the surface point with 1-w times another color (which might be black if we don't need it). The next section explains how to derive this equation for w.

Derivation of the Equation
For anyone interested (and because I didn't find it on the web) here is a derivation of the equation for w. We integrate the illumination over the hemisphere at distance 1 in a spherical coordinate system attached to the surface point with the direction of N in the direction of the y axis. If N and U point in the same direction, the integral is (apart from a constant color specified by the user):

$$\int_0^\pi \mathrm{d} \phi \int_0^\pi \mathrm{d}\theta \sin(\theta)\,\mathbf{L} \cdot \mathbf{N} =$$ $$\int_0^\pi \mathrm{d} \phi \int_0^\pi \mathrm{d}\theta \sin(\theta) \left( \begin{array}{c} x \\ y \\ z \end{array} \right)\cdot \mathbf{N} $$

The term sin(θ) is the Jacobian determinant for our integration on the surface of a sphere of radius 1, (x, y, z) is (cos(φ)sin(θ), sin(φ)sin(θ), cos(θ)), and N = (0,1,0). Thus, the integral becomes:

$$\int_0^\pi \mathrm{d} \phi \int_0^\pi \mathrm{d}\theta (\sin(\theta))^2 \sin(\phi) = \pi$$

The constant π will be included in the user-defined color of the maximum illumination. If there is an angle γ with cos(γ) = U·N between N and U, then the integration is only over a spherical wedge (from γ to π):

$$w = \frac{1}{\pi} \int_\gamma^\pi \mathrm{d} \phi \int_0^\pi \mathrm{d}\theta (\sin(\theta))^2 \sin(\phi)$$ $$= \frac{1}{2}(1 + \cos(\gamma))$$ $$= \frac{1}{2}(1 + \mathbf{U}\cdot\mathbf{N})$$

Shader Code
The implementation is based on the code from . In a more elaborated implementation, the contributions of other light sources would also be included, for example using the Phong reflection model as discussed in . In that case, hemisphere lighting would be included in the same way as ambient lighting.

Here, however, the only illumination is due to hemisphere lighting. The equation for w is:

$$w = \frac{1}{2}(1 + \mathbf{U}\cdot\mathbf{N})$$

We implement it in world space, i.e. we have to transform the surface normal vector N to world space (see ), while U is specified in world space by the user. We normalize the vectors and compute w before using w and 1-w to compute the illumination based on the user-specified colors. Actually, it is pretty straightforward.

Summary
Congratulations, you have finished another tutorial! We have seen:
 * What hemisphere lighting is.
 * What the equation for hemisphere lighting is.
 * How to implement hemisphere lighting.