I've recently found out just how wrong this article really was when I learned about Image-Based Lighting and Physically-based BRDFs. So if you want to see the correct implementation, please refer to my new RSRM blog post.
You really don't appreciate the difference it makes in lighting until you take a look at any of the idTech 4 games, and see just how bad Lambertian + Constant Ambient really looks. Problem is, proper global illumination is a tricky business. Seems like there is no one perfect solution that won't cost an arm and a leg to get quality results. So you can imagine how this has caused me much frustration in my own project.
Approaches I've considered:
- Hemisphere Lighting
- Irradiance volumes
- Spherical Harmonic Light Mapping (SHLM)
- Screen-Aligned Irradiance Volumes
- Dynamic Radiosity <several techniques>
- Dynamic illumination
- Influenced by surface normals
- Cheap to calculate offline and at runtime
- Low storage offline and at runtime
- Works in most situations, both indoors and outdoors
- Works over great distances
After much deliberation and experimentation, I settled on Skylights. While not ideal, they meet enough of my criteria to make them a good choice. Also, the fact that the game Brütal Legend uses them to great effect made me see how they could be viable in a real game. :)
This was where things got a little tricky. There didn't seem to be a whole lot of resources on the web about how to implement a system like this. There were a few on how to implement a dynamic skydome, but that was about it.
Having read several articles off the web, I derived a system that employed a 2D lookup texture which held gradients for altitudes, and time of day. From this I cobbled together something that employed bits from hemisphere lighting to look-up values in the texture. This provided enough for diffuse lighting, and glossy specular.
A proper metallic reflection took a bit longer, as it was clear that it would need a separate function that behaved very differently. This proved to be more difficult, and caused me to have limited success for several months. That was until I stumbled onto the article Dynamic Sky & Rain Effect. This helped me fill in most of the missing pieces to get some nice reflections, and a crude skybox (need to switch to skysphere).
Figure 1. 1, Sky diffuse lighting; 2, Sky glossy lighting; 3, Sky reflection; 4, skymap
Firstly, it seems that metallic reflections only look good with smooth geometry. As you can see from the third picture, they don't seem to like normal maps. This means that I can't have bumpy reflections, which is less than ideal, but not a deal-breaker.
Secondly, getting a nice horizon in metallic reflections required me to draw a dark line across the bottom of my gradient texture. While this worked for metallic reflections, it had the side effect of causing a black void in diffuse and glossy reflections. Since it would be too much of pain to produce two maps for every skylight, I'm guessing I will need to come up with some more complex function that darkens values below the horizon. That way, the burden of fixing this problem doesn't fall on an artist.
That's all I have to report right now. I'll keep everyone posted on future developments. ;)