# WebGL Lambertian shading

Move your cursor around the square above. Your cursor moves a light which illuminates a decorative relief. This is implemented with WebGL, using the fragment shader to the right. The fragment shader illuminates each pixel by consulting the following “normal map” image:

The normal map tells us, for each pixel, the “normal” at that point on the surface.
The normal is a vector which points perpendicular to the surface.
This vector has XYZ components which are encoded as RGB values.
The X component is encoded by the amount of red, and so on.
The red is in the range `[0, 1]`

,
and we convert this to the X component in the range `[-1, 1]`

.

The surface of the tile is completely matte.
It’s like wood, not like metal.
This is because the shader uses “Lambertian shading”,
which is a model of matte objects.
In Lambertian shading,
the intensity is proportional to `dot(normal_direction, light_direction)`

.
We can interpret this formula as answering the question,
“is the surface facing the light?”.
Note in particular that this formula does not depend on `camera_direction`

.
The illumination of shiny objects depends on `camera_direction`

because light is reflected towards the camera.
The illumination of matte objects does not depend on `camera_direction`

because the matte surface scatters light equally in all directions.

*Thanks to Sophie Lantreibecq, Ben Ellison, Andy Jones, Andreas Frisch, Luís Fonseca, and Callum Oakley
for helping me debug this over many beers.*

Tagged . All content copyright James Fisher 2017. This post is not associated with my employer.