Actually, you can calculate shadow volumes with vertex programs, just project every back-face vertex at a finite fixed distance. This is not the exact silhouette (has mush more polygons) but works with closed shapes and on-board generated geometry (like N-Patches). Also, there are more robust techniques that work with “open†shapes, but you have to change your geometry. I think I saw a couple of ATI/NVIDIA docs outlining the details.
Carmack said it was a bit slower on a GF3, but the CPU usage was low (about 10%).
As for shadow algorithms, I think the “Deep Shadow Maps†by Lokovic and Veach is currently the best practical algorithm. Ray casting is of course the most accurate and simple but is not yet practical if you don’t want just simple sharp opaque shadows.