Surface Shader examples
Surface Shader lighting examples

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 Lighting<Name> (SurfaceOutput s, UnityGI gi); This is used in forward rendering path for light models that are not view direction dependent (e.g. diffuse).

  2. half4 Lighting<Name> (SurfaceOutput s, half3 viewDir, UnityGI gi); This is used in forward rendering path for light models that are view direction dependent.

  3. half4 Lighting<Name>_Deferred (SurfaceOutput s, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal); This is used in deferred lighting path.

  4. half4 Lighting<Name>_PrePass (SurfaceOutput s, half4 light); This is used in light prepass (legacy 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 only works in forward, do not declare the _Deferred or _Prepass function. This way, all Shaders that use it compile to forward rendering only.

Custom GI

Similarly, customize the decoding lightmap data and probes by declaring the function below.

  1. half4 Lighting<Name>_GI (SurfaceOutput s, UnityGIInput data, inout UnityGI gi);

Note that to decode standard Unity lightmaps and SH probes, you can use the built-in DecodeLightmap and ShadeSHPerPixel functions, as seen in UnityGI_Base in the UnityGlobalIllumination.cginc file inside Unity ({unity install path}/Data/CGIncludes/UnityGlobalIllumination.cginc on Windows, /Applications/Unity/Unity.app/Contents/CGIncludes/UnityGlobalIllumination.cginc on Mac).

Examples

Surface Shader Lighting Examples

Surface Shader examples
Surface Shader lighting examples