This is the main shader for the mobile game Protectors. I decided to not use Unity's surface shader template, and made it from scratch using "Unlit" shader template, so I have full control of vertex shader and shading algorithms. And also it's not tightly bound to any Unity's render pipeline.
Shader uses 3 main textures:
-
albedo
rgb - color
alpha - tint mask
-
rm
r - roughness
g - metalness
b - ao + emissive
-
normal
ao & emissive packed into single channel by the following logic:
- ao values are stored in 0.0 - 0.5 range
- emissive values are stored in 0.5 - 1.0 range
and shader unpacks it with this simple function:
void unpackLight(in fixed packed, out fixed ao, out fixed emission)
{
fixed tmp = packed * 2;
ao = min(1, tmp);
emission = max(0, tmp - 1.05);
}
The goal of the first iteration was to replicate Unity's surface shader, but then I was able to improve shading of metals and glossy materials:
Since we're using baked lightmaps for the levels, I've noticed that most objects looked flat even when they use normal maps. And I decided to apply fake top light to the diffuse light layer using world space normals with this code:
light *= saturate(1 - abs(i.normalWS.y)) * normal.y + 1;
and here's the result:
Shader has several debug modes (Editor only), including texel debug for each texture
Shader also uses custom gradient fog and have extended version for characters