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 doesn't work

Discussion in 'Shaders' started by candycat, Oct 21, 2014.

  1. candycat

    candycat

    Joined:
    Jun 5, 2014
    Posts:
    29
    Hi, I'm trying to get the atten of a point light in a forwardadd pass, I add LIGHTING_COORDS in my v2f struct, and TRANSFER_VERTEX_TO_FRAGMENT in the vertex function. Then I use LIGHT_ATTENUATION to get the atten in the fragment function. But it seems that nothing changed when I move the point light away from my model.

    Here is my forwardadd pass code:
    Code (CSharp):
    1.         Pass {
    2.             Tags { "LightMode" = "ForwardAdd" }
    3.            
    4.             Cull Back
    5.             Lighting On
    6.             Blend One One
    7.            
    8.             CGPROGRAM
    9.            
    10.             #pragma vertex vert
    11.             #pragma fragment frag
    12.            
    13.             #include "UnityCG.cginc"
    14.             #include "Lighting.cginc"
    15.             #include "AutoLight.cginc"
    16.            
    17.             sampler _MainTex;
    18.             sampler _BumpTex;
    19.            
    20.             float4 _MainTex_ST;
    21.             float4 _BumpTex_ST;
    22.            
    23.             struct a2v {
    24.                 float4 vertex : POSITION;
    25.                 float3 normal : NORMAL;
    26.                 float4 texcoord : TEXCOORD0;
    27.                 float4 tangent : TANGENT;
    28.             };
    29.            
    30.             struct v2f {
    31.                 float4 pos : POSITION;
    32.                 float2 uv : TEXCOORD0;
    33.                 float2 uv2 : TEXCOORD1;
    34.                 float3 lightDirection : TEXCOORD2;
    35.                 LIGHTING_COORDS(3,4)
    36.             };
    37.  
    38.             v2f vert(a2v v) {
    39.                 v2f o;
    40.                
    41.                 TANGENT_SPACE_ROTATION;
    42.                 o.lightDirection = mul(rotation, ObjSpaceLightDir(v.vertex));
    43.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    44.                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    45.                 o.uv2 = TRANSFORM_TEX(v.texcoord, _MainTex);
    46.                
    47.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    48.                 return o;
    49.             }
    50.            
    51.             float4 frag(v2f i) : COLOR {
    52.                 float4 c = tex2D(_MainTex, i.uv);
    53.                 float3 n = UnpackNormal(tex2D(_BumpTex, i.uv2));
    54.                
    55.                 float3 lightColor = float3(0);
    56.                
    57.                 float lengthSq = dot(i.lightDirection, i.lightDirection);
    58.                 float atten = LIGHT_ATTENUATION(i);
    59.                
    60.                 // Angle to the light
    61.                 float diff = saturate(dot(n, normalize(i.lightDirection)));
    62.                 lightColor += _LightColor0.rgb * (diff * atten);
    63.                
    64.                 c.rgb = lightColor * c.rgb * 2;
    65.  
    66.                 return c;
    67.             }
    68.            
    69.             ENDCG
    70.         }
    What's wrong with it?
     
  2. candycat

    candycat

    Joined:
    Jun 5, 2014
    Posts:
    29
    I solved it myself. All thing is right when I add #pragma multi_compile_fwdadd.

    But I don't know why... What has multi_compile_fwdadd done?
     
  3. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    It tells Unity that this pass should be a forward add pass - this is the additive pass for all point/spot lights and for any extra directional lights (forward base gets the most prominent directional light - or no lights at all if there are no directional lights).
     
  4. candycat

    candycat

    Joined:
    Jun 5, 2014
    Posts:
    29
    Thanks for your reply. But i thought Tags { "LightMode" = "ForwardAdd" } had done that for me! The Doc said:
    • ForwardAdd: Used in Forward rendering; additive per-pixel lights are applied, one pass per light.
    So why i need to add #pragma multi_compile_fwdadd when i have already add Tags { "LightMode" = "ForwardAdd" } to the pass?
     
  5. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Not 100% sure.

    As far as I understand it, the LightMode tag doesn't tell Unity to compile the shader to be compatible as a forward add pass, only that it should be treated as one when it comes to rendering it.
     
  6. candycat

    candycat

    Joined:
    Jun 5, 2014
    Posts:
    29
    I found some info from this thread. Aras said, "If your shader pass doesn't have any LightMode tags, then no light variables are set up." So LightMode tags set some light variables, and #pragma multi_compile_fwdadd set something other? If i want to get everything right, i'd better add both of them to the pass. Am i right?
     
  7. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Yes, the pass should have both of them in order to fully work as forward add.
     
  8. candycat

    candycat

    Joined:
    Jun 5, 2014
    Posts:
    29
    Hope that Unity would provide more details. :(

    Thanks for the help.