There are 3 (main) types of lights: cone/spot lights, point lights and directional lights. Not everyone uses the same names though, so be careful when Googling.
- Cone/spot lights are lights which originate from a point but also have a direction which they shine in. Examples include a flashlight or a car's headlight.
- Point lights are lights which originate from a point in all directions, for example a candle.
- Directional lights are lights where the light comes from a point infinitely far away. It's often used for sun light since the sun is so far away that all the incoming light has essentially the same direction.
The basics are the same for all 3. You wish to create an view matrix the same way you create a view matrix for your camera, but instead create it with the parameters of your light, not your camera.
Shadows are implemented pretty differently for each one of these.
- Cone lights are the easiest thanks to their shape. You can easily set up a view matrix using gluLookAt():
- Eye position = light position.
- Center position = light position + light direction.
- Up vector = Anything as long as it isn't parallel to the light direction. (0, 1, 0) works for everything except when the light is pointing exactly up or down.
The perspective matrix is also easy to set up. The cone light has an angle which works exactly like the camera's field-of-view angle. You can therefore create a projection matrix the same way as you do for your camera.
- Point lights are much more complicated since they shine in all directions, but our shadow map is flat. You therefore need to have 6 shadow maps to form a cube around the light (can also be done using 2 shadow maps and some math magic). Needless to say, this gets complicated quickly so I'll just ignore them for now.
- Directional lights are as simple as cone lights to implement but it's much harder to get them to look right. You basically want the light's "position" to be the camera's position here so the shadows "follow" the camera. With that you have a position and a direction so you can easily set up a view matrix just like you did for cone lights. The perspective matrix is also pretty easy. Instead of using a projection matrix like your camera, you'll use an orthographic matrix. This essentially creates a huge box centered at the camera and oriented along the direction of the ligth. The problem here is that the shadow map cannot stretched over an infinitely large area since that would also require a shadow map of infinite resolution. Hence we need to limit the "range" of the directional light. This is done using the parameters to glOrtho(). The smaller you limit your area to, the sharper and better your shadows will look since the resolution of the shadow map will be distributed over a smaller area. A solution here is Cascaded Shadow Maps