Unity's Rendering Pipeline
Reference Manual > ShaderLab Reference > Advanced ShaderLab topics > Unity's Rendering Pipeline

Unity's Rendering Pipeline

Shaders define both how an object looks by itself (its material properties) and how it reacts to the light. Because lighting calculations must be built into the shader, and there are many possible light types, writing quality shaders that "just work" is an involved task. This document describes the pecularities of Unity's lighting&rendering pipeline and how the shaders need to be written to support all the different lights.

Light types and modes

In Unity, a Light can be Directional, Point or Spot light. Additionally, Ambient light level can be specified in Render Settings.

When any object is rendered, the lights that illuminate it are determined; and each light is chosen to render in Vertex or Pixel lighting mode. Per-pixel lighting usually looks a lot better, but is more expensive to render as well. So for each object, only some amount (specified in Quality Settings) of brightest lights are rendered in Pixel mode, while the remaining are rendered using Vertex lighting. When no lights are shining on an object, it is rendered in None mode.

Each object is then rendered in the following way:

Each pass in a shader communicates its lighting type (pixel, vertex etc.) via Pass Tags.

Vertex Lights

Vertex lights are rendered using "vertex" passes (see pass tags). All lights are rendered at once, using a fixed function OpenGL/Direct3D lighting model (Blinn-Phong). It is not possible to use vertex programs with vertex lights because vertex programs and fixed function lighting can be used at the same time. Note that it is still possible to use fragment programs, reading the interpolated diffuse and specular lighting colors.

In summary, vertex lighting is calculated automatically. All you do in a shader is use the calculated diffuse/specular colors, either in a fragment program or in the texture combiner setup. Vertex lights do not support light cookies.

Pixel Lights

Implementing a pixel lighting shader part is much more involved, mostly because there are different light types (directional, point, spot) and a shader must be able to process all of them. For pixel lights you also want to write a custom vertex program (using fixed function lighting does not make sense - you could just use vertex lights and get much better performance) where you must calculate the lighting yourself.

If you implement pixel lighting passes in the shader, most often you want to implement passes for the case when no lights are shining (ambient pass) as well. See Pass Tags for details.

The details of implementing light types in custom shaders are described in Attenuation and Cookies for Pixel Lights.