Our approach to the problem is to pregenerate a shadowmap that will be used as
a texture. To generate this map, we need two things: the heightmap and the
sun's position. Given the position of the sun, the calculation is very simple:
Draw a straight line from the sun to the point of interest in the heightmap.
If at any point the line's height is lower than the current height of the map,
the sun ray won't reach the point, which therefore will be black. In other
terms, as long as the sun ray isn't blocked by something in the terrain (like
a hill), it will directly hit the point we are examining, which in this case
will be white. Figure 1 will clear things up.
Figure 1: Sunray and covered pixels.
Some explanation for the image: The sunray v is a vector, its height at point
p is v(p). h(p) is the height of the terrain at point p.
To process the whole landscape, we simply iterate throug all pixels in the
heightmap and find out if they will be influenced by the light or not. This
is done with the steps in the following list:
- Fetch point of interest (POI) p
- Calculate vector v from p to sun
- Iterate through all pixels covered by v
- If v(p) ≤ h(p) at any pixel, stop iteration and mark it as black