Lighting is also pure math. Here you try to find out how much light falls
on an object when you know how many lights there are and where they are.
These mathematics make use of the direction of the light and the distance
between the light source and the vertex of the triangle. The light intensity
is only calculated at the vertices of the triangles that form the objects.
Now light calculations aren't that simple, because you have light sources
and light sources. There are 4 different types of light. First of all you
have a global light. A global light is a bit of a trick, being a base light
intensity level that is used to make sure that every object is somewhat
visible. So it's a bit like saying everything has a light intensity of 10
to start with. This kind of light is very handy if you are building up a
scene, just add a simple global light and everything will be visible. Naturally,
this kind of light is very boring since everything will look the same. To
change that we add uniform lights. Uniform lights emit light equally in
all directions, so every object can be lit by them as long as they are near
enough. The light intensity only depends on the distance between the vertex
and the light source. So all objects that are at the same distance from
the uniform light will get the same amount of light, whether they are above,
below or right doesn't matter- the direction is irrelevant. It's pretty
obvious that the math involved with this kind of lights are more expensive
than a simple global light source. But let's go a step further and add directional
lights. Directional lights will light objects based on distance and direction.
Let me illustrate this: assume you have a flashlight and you shine it onto
a side of a cube. In this case you will see a very bright surface. The direction
of the light is perpendicular to the surface. But now if you look at the
sides of the cube, where the direction of the light source is parallel to
the surface (same direction), you will notice that those sides are rather
dark compared to the first side. This effect is achieved by directional
lights. Most light sources in the real world are a mix between uniform and
directional lights. Pure forms are very rare but usually the directional
light source delivers better, more realistic results. But again, we have
to note that the math become more intense because now we need to look at
the distance, the direction of the light source and the orientation of the
surface. But we don't stop here: lets add spots. A spot is even more complex
since a very small zone will be lit very intense while further away from
the center of the spot the light intensity drops very fast. I'll not go
into the math but it's again obvious that it's more work…
Now while the operations for the Transformations were identical for every
vertex of every triangle of every object, the operations for the light sources
can be very different. In one scene you might have a couple of directional
lights while in another scene you might have a uniform light with a couple
of spots. On top of all this, the math involved is more intense for different
kinds of light and differences in math can result in differences in clock
cycles. So if a scene has a uniform light and a spot light it might very
well be that the hardware light engine requires 1 cycle to find the light
intensity caused by the uniform light while it requires 10 for the spot.
This imposes a risk for performance claims, if a company tells you that
the hardware light engine can handle 8 lights within x clockcycles, it will
probably mean 8 uniform lights. However, if you use spots or directional
lights the performance will drop considerably. Exactly how good the light
engine is remains thus to be seen… just be aware that there are lights and
there are lights.
This difference in clock cycles can give more problems as the hardware transform
and lighting engine might have completely different timings. Assume that
a transform takes 2 cycles, while a lighting takes between 1 and 10 cycles,
depending on the type of lights. This would introduce a bottleneck between
the two units. One of the two units will be idle waiting for the other to
finish. Buffers can help a bit but they can always suffer from under-runs
and overflows, so again timing can influence the actual throughput of these
engines.
Another question I ask myself is: How useful is hardware lighting in games?
Hardware lighting is per vertex lighting. The light intensity is only calculated
at the vertices of the triangles forming an object. In between the intensity
is interpolated between the values at the vertices. Now assume I want to
place a wall in my 3D world. A wall is just a rectangle and a rectangle
can be formed by two large triangles. No problem so far, but now I want
to add a torch casting a typical flickering light spot on the wall. Now
per vertex lighting only calculates light at the vertices, which would be
top left and right, and bottom left and right, in between you will get a
uniform interpolation. If we assume that the torch is right in the middle
of the wall then the distance to all corners is equal and thus the light
intensity will be the same for all vertices resulting in a completely uniform
lit wall. Not really what we wanted.