Search Unity

Question Discrepancy between documentation and Frame Debugger for unity_LightAtten

Discussion in 'General Graphics' started by victoria_h, Mar 26, 2023.

  1. victoria_h

    victoria_h

    Joined:
    Jul 12, 2020
    Posts:
    2
    Hi! I'm working on a project where I need to recreate the built-in pipeline's vertex lighting. I have everything working great except spotlights, and have run into a very strange issue. I am using 2019.4.16f1.

    In the docs unity_LightAtten is described as being:
    X = cos(spotAngle/2)
    Y = 1/cos(spotAngle/4)
    Z = quadratic attenuation
    W = squared light range

    I'm aware that W is unused in ShadeVertexLightsFull().
    And I deduced that z is actually = 25.0 / range*range.
    X is correct for spot angles in radians.

    It's the Y component that's been driving me crazy. By pointing a single spot light at a plane with any vertexlit shader and using the frame debugger to read its received values for unity_LightAtten while changing the light's Spot Angle, I've found that the formula provided in the docs can't possibly correct, or I'm making a really simple mistake. Here is the data I've collected.

    The first value is Spot Angle (in degrees) and the second is the unity_LightAtten.y that is getting passed to the shader.

    {179, 1.4256}
    {170, 1.538174}
    {160, 1.688059}
    {120, 2.732051}
    {105, 3.470881}
    {100, 3.794776}
    {90, 4.613126}
    {80, 5.75877}
    {70, 7.431356}
    {60, 10.00997}
    {50, 14.28811}
    {40, 22.16552}
    {30, 39.18637}
    {20, 87.81952}
    {15, 155.9076}
    {11, 289.6719}
    {10, 350.4453}
    {1, 35025.5}


    To be clear, this data is not the results of *my* code, it's the result of whatever the built-in pipeline is actually doing. I simply can't make my code match these results.

    Before it's suggested, I can't just use unity_LightAtten. I specifically need to recreate it.

    I've tried many methods of figuring out what the formula should be from this data but I can't make heads or tails of it. Can anyone glean what the actual implementation is from this data or point out what I could possibly be doing wrong?
     
  2. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    672
    Just a guess, haven't checked:

    In the shader, attenuation.y is used like this:
    Code (CSharp):
    1.             float rho = max (0, dot(toLight, unity_SpotDirection[i].xyz));
    2.             float spotAtt = (rho - unity_LightAtten[i].x) * unity_LightAtten[i].y;
    3.             atten *= saturate(spotAtt);
    4.  
    I found this equation for spotlight falloff on a Microsofts page:
    upload_2023-3-26_9-9-48.png

    If Unity is using this equation, unity_LightAtten.y would have to be
    1/(cos(umbra_angle_rad / 2) - cos(penumbra_angle_rad / 2))
     
  3. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    672
    Obviously, the next question is, what are the umbra and penumbra angles since you can't configure them.

    The umbra angle is probably the inner spot angle that you see in the debug view. Not sure about penumbra. There is a shadow angle as well but it is zero. Maybe the penumbra angle is just the spot angle?

    upload_2023-3-26_9-30-24.png
     
    victoria_h likes this.
  4. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    672
    Yeah, my assumption was right. unity_LightAtten.y is calculated like this
    1/(cos(umbra_angle_rad / 2) - cos(penumbra_angle_rad / 2))

    where umbra is 50% of the spot angle and penumbra_angle is just the spot angle.

    upload_2023-3-26_10-34-37.png

    Or in other words:
    unity_LightAtten.y = 1/(cos(spot_angle_rad / 4) - cos(spot_angle_rad / 2))
     
    Last edited: Mar 26, 2023
    victoria_h likes this.
  5. victoria_h

    victoria_h

    Joined:
    Jul 12, 2020
    Posts:
    2
    Aaaa you're right! Thank you so much <3 This is a life saver.

    It would be nice to finally have the documentation updated as well for anyone else, but at least there's now a forum post!
     
    c0d3_m0nk3y likes this.