Custom Lighting models in Surface Shaders

When writing Surface Shaders, you're describing properties of a surface (albedo color, normal, ...) and the lighting interaction is computed by a Lighting Model. Built-in lighting models are Lambert (diffuse lighting) and BlinnPhong (specular lighting).

Sometimes you might want to use a custom lighting model, and it is possible to do that in Surface Shaders. Lighting model is nothing more than a couple of Cg/HLSL functions that match some conventions. The built-in Lambert and BlinnPhong models are defined in Lighting.cginc file inside Unity ({unity install path}/Data/CGIncludes/Lighting.cginc on Windows, /Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc on Mac).

Lighting Model declaration

Lighting model is a couple of regular functions with names starting with Lighting. They can be declared anywhere in your shader file or one of included files. The functions are:

  1. half4 LightingName (SurfaceOutput s, half3 lightDir, half atten); This is used in forward rendering path for light models that are not view direction dependent (e.g. diffuse).
  2. half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten); This is used in forward rendering path for light models that are view direction dependent.
  3. half4 LightingName_PrePass (SurfaceOutput s, half4 light); This is used in deferred lighting path.

Note that you don't need to declare all functions. A lighting model either uses view direction or it does not. Similarly, if the lighting model will not work in deferred lighting, you just do not declare _PrePass function, and all shaders that use it will compile to forward rendering only.

Decoding directional lightmaps needs to be customized in some circumstances in a similar fashion as the lighting function for forward and deferred lighting. Use one of the functions below depending on whether your light model is view direction dependent or not. Both functions handle forward and deferred lighting rendering paths automatically.

  1. half4 LightingName_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal); This is used for light models that are not view direction dependent (e.g. diffuse).
  2. half4 LightingName_DirLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, half3 viewDir, bool surfFuncWritesNormal, out half3 specColor); This is used for light models that are view direction dependent.

Examples

Surface Shader Lighting Examples

Page last updated: 2012-01-23