GLSL Programming/Unity/Multiple Lights

This tutorial covers lighting by multiple light sources in one pass. In particular, it covers Unity's so-called “vertex lights” in the  pass.

This tutorial is an extension of. If you haven't read that tutorial, you should read it first.

Multiple Lights in One Pass
As discussed in, Unity's forward rendering path uses separate passes for the most important light sources. These are called “pixel lights” because the built-in shaders render them with per-pixel lighting. All light sources with the Render Mode set to Important are rendered as pixel lights. If the Pixel Light Count of the Quality project settings allows for more pixel lights, then some of the light sources with Render Mode set to Auto are also rendered as pixel lights. What happens to the other light sources? The built-in shaders of Unity render four additional lights as vertex lights in the  pass. As the name indicates, the built-in shaders render these lights with per-vertex lighting. This is what this tutorial is about. (Further lights are approximated by spherical harmonic lighting, which is not covered here.)

Unfortunately, it is somewhat unclear how to access the four vertex lights (i.e. their positions and colors). Here is, what appears to work in Unity 3.4 on Windows and MacOS X: Depending on your platform and version of Unity you might have to use  instead of ,   , and. Similarly, you might have to use  instead of. Note what's not available: neither any cookie texture nor the transformation to light space (and therefore neither the direction of spotlights). Also, no 4th component of the light positions is available; thus, it is unclear whether a vertex light is a directional light, a point light, or a spotlight.

Here, we follow Unity's built-in shaders and only compute the diffuse reflection by vertex lights using per-vertex lighting. This can be computed with the following for-loop inside the vertex shader: The total diffuse lighting by all vertex lights is accumulated in  by initializing it to black and then adding the diffuse reflection of each vertex light to the previous value of   at the end of the for-loop. A for-loop should be familiar to any C/C++/Java/JavaScript programmer. Note that for-loops are sometimes severely limited; in particular the limits (here: 0 and 4) have to be constants in Unity, i.e. you cannot even use uniforms to determine the limits. (The technical reason is that the limits have to be known at compile time in order to “un-roll” the loop.)

This is more or less how vertex lights are computed in Unity's built-in shaders. However, remember that nothing would stop you from computing specular reflection or per-pixel lighting with these “vertex lights”.

Complete Shader Code
In the context of the shader code from, the complete shader code is: The use of  and   appears to be necessary to make sure that no vertex lighting is computed when Unity doesn't provide the data.

Summary
Congratulations, you have reached the end of this tutorial. We have seen:
 * How Unity's vertex lights are specified.
 * How a for-loop can be used in GLSL to compute the lighting of multiple lights in one pass.