Search Unity

Getting to the bottom of point light attenuation squares.

Discussion in 'Shaders' started by IronMathbook, Nov 25, 2016.

?

How many of you have run into this problem before.

  1. yes

    100.0%
  2. no

    0 vote(s)
    0.0%
  1. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    Point light are square in vert frag shades. The range of the light isn't being applied so thing look square.
    This problem has been going on for a while but the issue seems like it's being ignored. Or people try and pretend that it doesn't exist.
    Sorry for making this question sloppy with links but there are there to prove that this is and ongoing issue and there have been various incorrect solutions over there years.

    Here is the code I'm using for light direction/ light attenuation.
    Code (CSharp):
    1. half3 facetolite=(_WorldSpaceLightPos0.xyz - posMain.xyz);
    2. half distance = length(facetolite);
    3. //atten problem with spotlights and point lights
    4. o.lightDir = half4(normalize(lerp(_WorldSpaceLightPos0.xyz,facetolite,_WorldSpaceLightPos0.w)),
    5. lerp(1.0,1/(distance*distance),_WorldSpaceLightPos0.w));
    I have tried everything I can think of including solution from here
    https://forum.unity3d.com/threads/g...ight-in-forward-add-mode.213430/#post-1433291
    and here
    https://github.com/candycat1992/Unity_Shaders_Book/issues/47

    I looked at Catlike coding's explanation for why this happens here.
    http://catlikecoding.com/unity/tutorials/rendering/part-5/

    Catlike coding suggest that [ tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr] is what is responsible for the clipping range and that range.
    Code (CSharp):
    1. #ifdef POINT
    2. uniform sampler2D _LightTexture0;
    3. uniform unityShadowCoord4x4 unity_WorldToLight;
    4. #define UNITY_LIGHT_ATTENUATION(destName, input, worldPos) \
    5.     unityShadowCoord3 lightCoord = \
    6.         mul(unity_WorldToLight, unityShadowCoord4(worldPos, 1)).xyz; \
    7.     fixed destName = \
    8.         (tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr). \
    9.         UNITY_ATTEN_CHANNEL * SHADOW_ATTENUATION(input));
    10. #endif
    However they also say that the clipping range is always one. If the tex2D isn't the cause of the clipping range they are not making things clear.

    Looked at and modified the AutoLight.cginc and UnityCG.cginc. Disabled both and see what happens. If I don't include either I get the same problem. Tried messing around with _LightMatrix0 and _ LightTexture0 and no luck.
    I believe that _ LightTexture0 is always a solid color. I tried replacing the light texture by making a user variable. There was a change in the light intensity with some textures but the point light stayed square.
    Using attenuation = 1 / (1.0 + distance*distance) or attenuation = 1 / (1.0 + distance) still had the same problem. It doesn't matter how many point lights I have either and I have two passes before you ask.
    I'm thinking that whatever is going on is not related to any of the include files anymore and this is a problem with Unity its self.

    There is one thing that I think a few of us have in common who have this problem. We used the unity cookie tutorial which was the only vert frag tutorial out there for a while.
    http://answers.unity3d.com/questions/566012/what-is-the-proper-way-of-calculating-attentuation.html
    //
    https://forum.unity3d.com/threads/problem-with-point-light-in-own-shader.194050/
    //
    http://answers.unity3d.com/questions/823024/cg-programming-points-lights-attenuation-and-light.html
    //
    http://answers.unity3d.com/questions/1080447/why-is-this-point-light-square.html
    //
    https://www.reddit.com/r/Unity3D/comments/35qz78/point_light_attenuation/

    I'm thinking about quitting unity if I can't at lease get a definitive anwser about whats going on.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    The issue you're running up against is something you can't find in the shader. The attenuation texture lookup will produce a circular shape with the edge completely black, so it's not that. The vertex shader light attenuation calculation is different than the usual per pixel texture based attenuation, and that has an infinite falloff range.

    The real issue is Unity masks additive light passes with a screen or stencil mask to limit the area they draw to only the screen area that their light range is supposed to touch when using the default per pixel falloff. That means if you change the falloff calculation to be larger than the default you'll see it clip. The only work around for this is to make your lights larger and adjust your custom falloff to look the way you want.
     
    jonbro5556 likes this.
  3. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    Okay that explains why nothing related to shaders has had any effect. Thank you for answering, I've been at wits end trying to figure this out.
    Is there away to modify Unity's additive light pass stencil size or at the worst force point-lights to use the base pass.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    There's no way to modify the mask other that I know of other than with the radius of the light, and you can't make the normal per pixel lights work in the base pass because that's not how Unity's lighting system works. You can use per vertex lights in the base pass, and even do then in the fragment shader to work with normal maps (thus being per pixel), but like normal vertex lights they won't match the usual per pixel lights for the reasons I mentioned above.

    To do what you want requires completely replacing Unity's lighting system, kind of like Valve's The Lab Renderer. Unity is also working on its scriptable render loop system, which had no ETA for release, but would allow for more control for stuff like this. In fact over of the things they are working on now using it is a forward renderer where all lights are rendered in a single per mesh pass.
     
    TeRain likes this.