I understand the light attenuation is calculate from a texture read. Can someone tell me how that texture is calculated exactly? Thanks
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): #ifdef POINT #define LIGHTING_COORDS(idx1,idx2) float3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2) uniform sampler2D _LightTexture0; uniform float4x4 _LightMatrix0; #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(_LightMatrix0, mul(_Object2World, v.vertex)).xyz; TRANSFER_SHADOW(a) #define LIGHT_ATTENUATION(a) (tex2D(_LightTexture0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * SHADOW_ATTENUATION(a)) #endif #ifdef SPOT #define LIGHTING_COORDS(idx1,idx2) float4 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2) uniform sampler2D _LightTexture0; uniform float4x4 _LightMatrix0; uniform sampler2D _LightTextureB0; #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(_LightMatrix0, mul(_Object2World, v.vertex)); TRANSFER_SHADOW(a) inline fixed UnitySpotCookie(float4 LightCoord) { return tex2D(_LightTexture0, LightCoord.xy / LightCoord.w + 0.5).w; } inline fixed UnitySpotAttenuate(float3 LightCoord) { return tex2D(_LightTextureB0, dot(LightCoord, LightCoord).xx).UNITY_ATTEN_CHANNEL; } #define LIGHT_ATTENUATION(a) ( (a._LightCoord.z > 0) * UnitySpotCookie(a._LightCoord) * UnitySpotAttenuate(a._LightCoord.xyz) * SHADOW_ATTENUATION(a) ) #endif
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.
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.
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.
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.
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
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).
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.