Search Unity

How to change how light fades.

Discussion in 'Universal Render Pipeline' started by krokots, Jan 21, 2020.

  1. krokots

    krokots

    Joined:
    Oct 3, 2017
    Posts:
    6
    I have a problem when I use URP and point lights, the attenuation function does not produce expected results.

    Changing intensity either makes everything too dark or near surfaces are way too bright. I'd like to reduce that extremely bright effect. How can I deal with this?
     
    Matt-Cranktrain likes this.
  2. sebsmax

    sebsmax

    Joined:
    Sep 8, 2015
    Posts:
    118
  3. krokots

    krokots

    Joined:
    Oct 3, 2017
    Posts:
    6
    What is the differance between attenuation there, and here:
    https://github.com/Unity-Technologi...pelines.universal/ShaderLibrary/Lighting.hlsl ?
    Earlier I tried modifying function DistanceAttenuation, this line:
    Code (CSharp):
    1. float lightAtten = rcp(distanceSqr);
    I replaced with something like this :
    Code (CSharp):
    1. float lightAtten = 0.4f / ((distanceSqr * 0.05f) + 1.0f);
    This works well on flat surfaces, but whenever object is slanted, there are problems. There is a function "AngleAttenuation" but I don't know how to modify it.
    Also, If i would modify ForwardLights (assuming this works on point lights) what part I need to change? I see there is this part
    Code (CSharp):
    1. float lightRangeSqr = lightData.range * lightData.range;
    2.                 float fadeStartDistanceSqr = 0.8f * 0.8f * lightRangeSqr;
    3.                 float fadeRangeSqr = (fadeStartDistanceSqr - lightRangeSqr);
    4.                 float oneOverFadeRangeSqr = 1.0f / fadeRangeSqr;
    5.                 float lightRangeSqrOverFadeRangeSqr = -lightRangeSqr / fadeRangeSqr;
    6.                 float oneOverLightRangeSqr = 1.0f / Mathf.Max(0.0001f, lightData.range * lightData.range);
    7. matches the GI.
    8.                 lightAttenuation.x = Application.isMobilePlatform ? oneOverFadeRangeSqr : oneOverLightRangeSqr;
    9.                 lightAttenuation.y = lightRangeSqrOverFadeRangeSqr;
    I try to play with these values later.
    Here is how it works when no angled surfaces are on view:
    Bez tytułu1.png
    This is where you can see problems :
    Bez tytułu2.png
     
    Last edited: Jan 23, 2020
  4. sebsmax

    sebsmax

    Joined:
    Sep 8, 2015
    Posts:
    118
    I don't know much about it, I had the same issue than you, so i looked how to modify it, but once I found it, I jumped on something else!

    I'm assuming the the light spread per object and the distance attenuation on a gamebject are different, and should match.

    If it doesn't, the light attenuation will start at a different intensity and it will not look good.

    Maybe someone working on the SRP can confirm?

    However, if you find good settings, don't hesitate to share your results :D
     
  5. sebsmax

    sebsmax

    Joined:
    Sep 8, 2015
    Posts:
    118
    Hey @krokots,
    I've modifed on my side the way the light is applied, It's not exactly what I want, but it does the trick.

    here are my changes in the ForwardLights.cs
    Code (CSharp):
    1.  
    2.  
    3.                 // float lightRangeSqr = lightData.range * lightData.range;
    4.                 // float fadeStartDistanceSqr = 0.8f * 0.8f * lightRangeSqr;
    5.                 // float fadeRangeSqr = (fadeStartDistanceSqr - lightRangeSqr);
    6.                 // float oneOverFadeRangeSqr = 1.0f / fadeRangeSqr;
    7.                 // float lightRangeSqrOverFadeRangeSqr = -lightRangeSqr / fadeRangeSqr;
    8.                 // float oneOverLightRangeSqr = 1.0f / Mathf.Max(0.0001f, lightData.range * lightData.range);
    9.  
    10.                 // On mobile: Use the faster linear smoothing factor.
    11.                 // On other devices: Use the smoothing factor that matches the GI.
    12.                 // lightAttenuation.x = Application.isMobilePlatform ? oneOverFadeRangeSqr : oneOverLightRangeSqr;
    13.                 // lightAttenuation.y = lightRangeSqrOverFadeRangeSqr;
    14.                
    15.  
    16.                 //simplified calculation
    17.                 float lightRangeSqr = lightData.range * lightData.range;
    18.  
    19.                 lightAttenuation.x = 1.0f / -lightRangeSqr;
    20.                 lightAttenuation.y = -1;
    21.  
    From what I could understand, the comment at the line 137 explain how they do the attenuation, but it's a bit tricky:
    Code (CSharp):
    1.  
    2.                 // smoothFactor =  distanceSqr * (1.0 / (fadeDistanceSqr - lightRangeSqr)) + (-lightRangeSqr / (fadeDistanceSqr - lightRangeSqr)
    3.                 //                 distanceSqr *           oneOverFadeRangeSqr             +              lightRangeSqrOverFadeRangeSqr
    The distanceSqr is calculated in the shader (Lighting.hlsl, line 142), while the oneOverFadeRangeSqr and lightRangeSqrOverFadeRangeSqr are calculated in the ForwardLights.cs, it's lightAttenuation.x and lightAttenuation.y

    So if you want a linear approach, you need to change the value on both side
     
  6. krokots

    krokots

    Joined:
    Oct 3, 2017
    Posts:
    6
    Thanks, I'll be experimenting with this as soom as I go back to the visual aspect of my game. Very nice!