I was approached by a team of guys who were looking to achieve an aesthetic similar to that of Monument Valley.
The idea seemed simple enough, Monument Valley uses a shader which has 3 hard-coded directional lights along the cardinal axes of their world. They have a custom lighting falloff calculation to smooth out the transition between between lights, avoid the high and low points typical of the traditional model.
What I soon learned was that Monument Valley can do that so simply because of their use of an Orthographic camera, an isometric perspective and 90% of their world geometry is axis-aligned, none of which was the case for the game being made by this team of talented guys! Their game was full 3D, dynamic perspective, and mostly curved shapes.
So, after a good while of thinking and tinkering, some exploration through multiple co-ordinate systems, and a non-stop barrage of mathematical gotchas and headaches. I arrived at a solution.
We would define 6 axis-aligned directional lights, sample the lighting for every point on a unit-sphere, bake the lighting out into a texture map and use a, relatively simple, lookup to light the object.
What we ended up with is a beautifully smooth transition between lights, normal mapping and transparency support, 6 per-pixel lights stored in a single 32×64 texture, and all of that for approximately the same runtime cost as the built-in Unity Bumped shader with 0 lights.
Not to mention an idea for a possible future experiment for cheap global illumination…