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

Adding attenuation texture to Light component.

Discussion in 'Shaders' started by bonniemathew, Jul 20, 2016.

  1. bonniemathew

    bonniemathew

    Joined:
    Jun 10, 2016
    Posts:
    11
    Hi,

    I want to control the attenuation of lights (per light basis). Is it possible to attach a 1D attenuation texture to the Light component (like light cookie)?

    If I can do that, then I can modify the LIGHT_ATTENUATION macro in the AutoLight.cginc file to look up from the 1D texture that I have set. I am able to set the _LightTexture0 from my script. But the problem is that this change will affect all the point lights. I want to have control over attenuation of individual point lights ie each point light should have its own attenuation texture. Each light should take its own attenuation texture in its render pass. How to do it ?

    #ifdef POINT
    #define LIGHTING_COORDS(idx1,idx2) unityShadowCoord3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
    #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



    Bonnie
     
  2. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    You should roll out your own lighting system then, ie you pass custom position to the shader from which you have associated tag to let it know which attenuation, custom position bound to your own implementation of light culling/proximity to objects.
     
  3. bonniemathew

    bonniemathew

    Joined:
    Jun 10, 2016
    Posts:
    11
    Thanks for the reply @neoshaman !!

    I couldn't follow what you said as I am quite new to Unity. Did you mean having custom attenuation equation that takes position of light as input and gives the corresponding atten value? Even in that case, it will behave the same for all point lights right? Can I have the flexibility of having its own attenuation function per point light ?
     
  4. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    It's nothing to do with unity and all to do with shader.

    start here
    https://en.wikibooks.org/wiki/Cg_Programming/Unity
    basically shader are program, if you want custom light, program custom light, unity provide some sugar to help you with common case that's all.
     
  5. bonniemathew

    bonniemathew

    Joined:
    Jun 10, 2016
    Posts:
    11
    OK.. Now I understand what you meant. To write a surface shader to handle custom lighting..Right? Hmm..then it will be applied to the materials and then to game objects. But I was trying to add a per light (instead of per material) parameter (texture) so that all the objects affected by this light will follow the attenuation texture set for that light.

    Anyway, light cookies are the only per light texture that can be set now. Also, found from @Aras that per light parameters may come in future.

    ARAS PRANCKEVIČIUS
    FEBRUARY 11, 2015 AT 5:43 PM /
    Ability to add custom per-light parameters on any light is high on my “list of things to do”, but not today. I’m thinking about perhaps ability to add a MaterialPropertyBlock per light, that then could be consumed by any shaders that deal with said light (either in forward or deferred).
    http://blogs.unity3d.com/2015/02/06/extending-unity-5-rendering-pipeline-command-buffers/
     
  6. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    There is no "per light" attribute in reality, it's because all material shader are fed the same data there is some kind of consistency, that's part of the sugar.

    What they do is that they have a structure here they store light data, and then you don't have to declare it explicitly in all custom shader, only acess its member. So when you are doing a toon shading you don't have to detect if the light attribute (directional, point or spot) because it is already compute for you in a series of sugar variable (atten and other), that's what adding the *.cginc do (like autolight.cginc or unityCG.cginc).

    What you can do is to make your own structure, then access them in the materail, just like the unity sugar, why not make your own *.cginc to define light and include it in any mat you need the extra data.
     
  7. bonniemathew

    bonniemathew

    Joined:
    Jun 10, 2016
    Posts:
    11
    Thanks for the reply.

    Is there any way to know which Light Pass is going on in the shader? As I understand, the ForwardAdd pass happens for each light in the scene. If I know in the Shader which light's pass is going on then I can apply that light's specific properties while shading.

    For eg: I have one object in the scene and is being lit by PointLight A and PointLight B. PointLight A is the default point light and PointLight B is a having a different way of attenuation which is being defined in a 1D texture. As per my understanding (please correct me If I am wrong), the scene object will be rendered in 2 passes. 1st pass with PointLightA and 2nd pass with PointLight B. So only during the PointLight B's pass I should do the texture lookup for getting attenuation value.
    This is the scenario I am having. How this scenario can be handled?
     
  8. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    I don't think that's that simple.

    My assumption is:
    - basically light are transform in the scene
    - we then find the closest light volume to the object and put them into a structure in order
    - we use the structure to compute light

    So there is no guarantee that the order of pass (ie the order of light in the structure) match the order of light put in the scene.

    Unity itself pick only the 4 most important light (likely teh closest) and accumulate other in a simpler representation (spherical harmonics) to save compute time.

    So you will have to create a structure with a limited number of light for the whole scene, then pass it to shader, no culling, so the order always remain the same. Or you need to create a structure that pass those lights with extra data so you can cull objects outside the influence of the light.

    How you implement this is all up to you.
     
    bonniemathew likes this.
  9. bonniemathew

    bonniemathew

    Joined:
    Jun 10, 2016
    Posts:
    11
    Thanks..
    I was able to implement a basic version.. Basically, I am sending 4 light positions and its attenuation textures to the shader, and in each light pass I find out which light it is by comparing with the light positions. Then use that particular light's attenuation texture.
     
    neoshaman likes this.