Search Unity

Light attenuation function

Discussion in 'Shaders' started by cybie, Dec 17, 2010.

  1. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    91
    I understand the light attenuation is calculate from a texture read. Can someone tell me how that texture is calculated exactly?

    Thanks
     
  2. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    91
    Or more specifically, how does Unity calculate the attenuation value for the point and spot.
     
  3. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    This is copied from AutoLight.cginc, which is in your Unity install. The LIGHT_ATTENUATION macros are what you want. Check out the whole file for other light types (and shadowed lights).
    Code (csharp):
    1. #ifdef POINT
    2. #define LIGHTING_COORDS(idx1,idx2) float3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
    3. uniform sampler2D _LightTexture0;
    4. uniform float4x4 _LightMatrix0;
    5. #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(_LightMatrix0, mul(_Object2World, v.vertex)).xyz; TRANSFER_SHADOW(a)
    6. #define LIGHT_ATTENUATION(a)    (tex2D(_LightTexture0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * SHADOW_ATTENUATION(a))
    7. #endif
    8.  
    9. #ifdef SPOT
    10. #define LIGHTING_COORDS(idx1,idx2) float4 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
    11. uniform sampler2D _LightTexture0;
    12. uniform float4x4 _LightMatrix0;
    13. uniform sampler2D _LightTextureB0;
    14. #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(_LightMatrix0, mul(_Object2World, v.vertex)); TRANSFER_SHADOW(a)
    15. inline fixed UnitySpotCookie(float4 LightCoord)
    16. {
    17.     return tex2D(_LightTexture0, LightCoord.xy / LightCoord.w + 0.5).w;
    18. }
    19. inline fixed UnitySpotAttenuate(float3 LightCoord)
    20. {
    21.     return tex2D(_LightTextureB0, dot(LightCoord, LightCoord).xx).UNITY_ATTEN_CHANNEL;
    22. }
    23. #define LIGHT_ATTENUATION(a)    ( (a._LightCoord.z > 0) * UnitySpotCookie(a._LightCoord) * UnitySpotAttenuate(a._LightCoord.xyz) * SHADOW_ATTENUATION(a) )
    24. #endif
     
  4. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    91
    Thanks, I understand that the attenuation function is stored in the texture, _LightTexture0. But my question is how was _LightTexture0 calculated.

    Also, is it possible to replace this _LightTexture0 with a different attenuation function?

    Thanks.
     
  5. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    I don't know what function is used, although you could plot it with a custom shader. You can write your own lighting function and reference whatever textures you like for surface shaders, or you can write a classical vertex/fragment combination and do lighting however you want.
     
  6. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    91
    In the deferred path (which is what I want to use), it looks like the attenuation term is not available at the surface shader stage. And that makes sense since the attenuation term is lost in the light accumulation buffer.

    it would be great if the attenuation texture is exposed to the users in the future.
     
  7. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    did you check the builtin shader package to see if the shader is there but not accessable normally?
     
  8. Per

    Per

    Joined:
    Jun 25, 2009
    Posts:
    460
    Realistic light falloff should follow the inverse square rule. The function is simply the inverse distance to the power of 2, i.e. value = (normal length / distance from source) ^ 2
    .

    This means that to calculate a bitmap you can simply use a square of the linear gradient value across the image for each point.
     
    Last edited: Dec 20, 2010
    Thomas-Mountainborn likes this.
  9. RamzaB

    RamzaB

    Joined:
    Nov 4, 2012
    Posts:
    42
    I know this is an old thread, but just in case someone else is wondering how _LightTexture0 calculated.

    It's not actually calculated per se. It's a texture that you give to the light in order to project that texture to the environment.
    Unity calls it "cookie"
    https://docs.unity3d.com/Documentation/Components/class-Light.html
     
  10. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,368
    Wrong, you are talking about the light cookies. People here are talking about the actual attenuation (falloff, range) of the light which is stored in lookup textures: _LightTexture0 and _LightTexture0B (the actual lookup attenuation table plus the cookie defined in the light component itself).
     
  11. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    I will boldly necrobump!
    if you want to change to Realistic light falloff what do you do with _LightTexture0 and _LightTexture0B and where is the lookup attenuation table.