Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Light attenuation parameter

Discussion in 'Shaders' started by lumoconnor, Jul 26, 2019.

  1. lumoconnor

    lumoconnor

    Joined:
    Jan 17, 2016
    Posts:
    27
    Hello!

    I'm modifying a standard surface shader so that I can specify the colour of the shadows cast on the surface. I'm doing this by modifying the lighting model.

    I was initially using this lighting function, which makes use of the atten parameter:

    Code (CSharp):
    1. half4 LightingCSLambert(SurfaceOutput s, half3 lightDir, half atten) {
    2.     fixed diff = max(0, dot(s.Normal, lightDir));
    3.     fixed4 c;
    4.     c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
    5.     c.a = s.Alpha;
    6.     c.rgb += _ShadowColor.xyz * max(0.0, (1.0 - (diff*atten * 2))) * _DiffuseValue;
    7.     return c;
    8. }
    I've switched to this function, which allows me to make use of physically based shading. But I no longer have access to the atten parameter:

    Code (CSharp):
    1. half4 LightingCSStandard(SurfaceOutputStandard s, float3 viewDir, UnityGI gi)
    2. {
    3.     s.Normal = normalize(s.Normal);
    4.     half oneMinusReflectivity;
    5.     half3 specColor;
    6.     s.Albedo = DiffuseAndSpecularFromMetallic(s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
    7.     // shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
    8.     // this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
    9.     half outputAlpha;
    10.     s.Albedo = PreMultiplyAlpha(s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
    11.     half4 c = UNITY_BRDF_PBS(s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
    12.     // Add coloured shadows
    13.     fixed diff = max(0, dot(s.Normal, gi.light.dir));
    14.     half atten = 1.0;
    15.     c.rgb += _ShadowColor.xyz * max(0.0, (1.0 - (diff*atten * 2))) * _DiffuseValue;
    16.     c.a = outputAlpha;
    17.     return c;
    18. }
    So, just wondering if anyone knows the PBS equivalent of the atten parameter and how to access it? Struggling to find anything in the documentation that would help.

    Thanks for your help!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Sadly, there isn't one. When using that Lighting function style the atten is pre-multiplied onto the light color that comes in with the UnityGI struct. Luckily it doesn't do anything else so it can be extracted, as long as the light's color isn't too dark.
    Code (csharp):
    1. half3 attenRGB = gi.light.color / max(_LightColor0.rgb, 0.0001);
    2. half atten = max(attenRGB.r, max(attenRGB.g, attenRGB.b));
     
    XelX0r likes this.
  3. lumoconnor

    lumoconnor

    Joined:
    Jan 17, 2016
    Posts:
    27
    Fantastic, will try this out. Thanks for the help!