If you want to learn how to do lighting, I recommend Real-Time Rendering, specifically chapter 5. From what I have seen, the book goes into great detail on the subject of lighting in later chapters as well.
I currently have experience with two types of lights: directional and omni. A directional light is basically a light which shines everywhere in one direction. Directional lights are commonly used for the sun, and other far-off light sources. An omni light is a type of point-light; it shines from a specific point in all directions. These would be used for things like torches, fireballs, sci-fi weapon projectiles, lamps without a shade, etc. There is another type of point-light called a "spotlight", which only shines within a specific set of directions (a cone).
Lighting requires two properties from a material: specular and diffuse. Currently, the specular property is constant over the entire model. Textures supply the diffuse property on a pixel-by-pixel basis, allowing the artist to finely tune how the model will look. A texture is pretty much a diffuse map.
Today I learned about a couple things you want to watch out for when setting shader constant registers. The first is that if you are passing in an array all in one call to Set*ShaderConstant*(), each array element must be packed to align with a 4-float/int boundary. I tried passing in an array where each element was a float3 and I was initially rather confused as to why it wouldn't work.
The second thing I would like to point out is that there is apparently a separate set of registers for integers. If you need to pass an integer to your shader, make sure you are using Set*ShaderConstantI() and not Set*ShaderConstantF(). This one took me a while to figure out, which was a little embarrassing.
I am now researching shadows. Unfortunately, it appears as though creating shadows from omni lights is a bit of a black art... It involves creating 6 shadow maps and cube mapping with them or something. I should have more details tomorrow.
[size="1"]Reposted from http://invisiblegdev.blogspot.com/
The advantage of this is that you only have to render 2 shadowmaps (instead of 6)... And if you think about lighting in a game context and use a kind of hemisphere light (same as a omni, but with just one direction, like half a sphere), you can cut that down to only 1 shadowmap...
My implementation's results ends up being something like [url="http://www.youtube.com/watch?v=OhzO2pnDNnQ"]http://www.youtube.com/watch?v=OhzO2pnDNnQ[/url] . In that scene you have 100 lights, with dynamic updates (with a LOD algorithm), and with "soft shadowing" for the closer lights...