- Home /
Is the documentation for surface shader custom lighting functions wrong?
In the documentation for Custom lighting models in Surface Shaders it is stated that the functions used to define your custom lighting model should conform to one of four conventions, depending on the information you need:
- half4 Lighting<Name> (SurfaceOutput s, UnityGI gi);
- half4 Lighting<Name> (SurfaceOutput s, half3 viewDir, UnityGI gi);
- half4 Lighting<Name>_Deferred (SurfaceOutput s, UnityGI gi, out half4 outDiffuseOcclusion, out half4 outSpecSmoothness, out half4 outNormal);
- half4 Lighting<Name>_PrePass (SurfaceOutput s, half4 light);
The documentation for Surface Shader lighting examples however uses entirely different parameters:
half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten);
half4 LightingSimpleSpecular (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
Is the documentation wrong or incomplete? It doesn't describe the attenuation or light direction parameters at all, so I have no idea how to interpret the former, nor can I be sure if the latter, for instance, is normalized.
Answer by Namey5 · Feb 15, 2021 at 09:01 PM
The former is more recent and how surface shaders probably should be written; the latter hasn't really changed since surface shaders were introduced nearly a decade ago, however both will still work just fine. 'lightDir' and 'viewDir' are both normalized (and in world space - might not seem like a necessary clarification but it is), 'atten' is the combined distance, shadow and cookie attenuation for any given light.
But if the former is the most recent version, how does one get the light direction and attenuation when using those methods?
Those parameters are now part of the UnityGI struct that is passed instead;
struct UnityLight
{
half3 color;
half3 dir;
half ndotl; // Deprecated: Ndotl is now calculated on the fly and is no longer stored. Do not used it.
};
struct UnityIndirect
{
half3 diffuse;
half3 specular;
};
struct UnityGI
{
UnityLight light;
UnityIndirect indirect;
};
So in this case, you would write;
half4 LightingCustom (SurfaceOutput s, half3 viewDir, UnityGI gi)
{
half3 lightDir = gi.light.dir;
half diff = max (0, dot (normalize (s.Normal), lightDir));
//At a guess, atten seems to be baked into light.color
half4 c;
c.rgb = (s.Albedo.rgb * gi.light.color) * diff;
c.a = s.Alpha;
return c;
}
I don't remember if Unity has an automatic GI function, so you may need to define your own.
Your answer
Follow this Question
Related Questions
Dynamic Parameters/Arguments 1 Answer
How to add Zbuffer to Custom Surface Shader 1 Answer
why does IN.screenPos in a surface shader have different Z values on Windows and Android? 2 Answers
What happens when the alpha value is outside the 0..1 range in surface shader lighting models? 0 Answers
Get local position in surface shader 2 Answers