You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The physically correct rate for light attenuation is 1/r^2, where r is the distance between the surface and the point light. We used to use a 1/r equation. This is common in colorspace-oblivious rendering since after taking into account that in sRGB a color channel of x produces an amount of light proportional to about x^2.2, the effective attenuation is 1/r^2.2 which is pretty close to 1/r^2. In a979351 the equation was changed from 1/r to 1/r^2. I doubt this was a good idea since now the effective attenuation is an excessive 1/r^4.4. In a linear colorspace we would obviously want to use 1/r^2.
With the introduction of sRGB/linear colorspace, there is the question of how to make a dynamic light API that will give consistent results between the colorspaces. The idea from the current version of #1687 seems OK: a 0-1 RGB color which is interpreted as sRGB, and an intensity which should always be interpreted as linear. Then we could use the formula convertToSRGB(color)/r^2 for the linear colorspace, and if we want to get identical results in the sRGB colorspace, color / r^(2 / 2.2) = color / r^0.90909. To make this API, unfortunately we will have to undo the changes to the 0.56 branch which got rid of the separate 'intensity' argument in favor of unbounded r/g/b.
In a979351 the equation was changed from 1/r to 1/r^2. I doubt this was a good idea since now the effective attenuation is an excessive 1/r^4.4.
I got this backward, the attenuation there would be 1/r^1.1 not 1/r^4.4.
Anyhow, the equation we are currently using (the red line) actually isn't very close to 1/r^2. On this graph x is the distance as a proportion of the light's "radius" (cutoff distance) and y is the attenuation. x = 1 is the cutoff point where a light will not be selected for the light tile if the distance is greater than this. The 1/x and 1/x^2 curves are scaled so that they cross at x = 1. I would say our curve looks closer to 1/r. (One can try different constant factors, but I couldn't make 1/x^2 any closer that way.)
Since the a given numerical color value in the 0-1 range represents a brighter light in linear space than in sRGB, the attenuation cutoff is too high in linear mode, resulting in hard edges on the light tiles.
Activity
slipher commentedon Mar 11, 2026
I got this backward, the attenuation there would be 1/r^1.1 not 1/r^4.4.
Anyhow, the equation we are currently using (the red line) actually isn't very close to 1/r^2. On this graph x is the distance as a proportion of the light's "radius" (cutoff distance) and y is the attenuation. x = 1 is the cutoff point where a light will not be selected for the light tile if the distance is greater than this. The 1/x and 1/x^2 curves are scaled so that they cross at x = 1. I would say our curve looks closer to 1/r. (One can try different constant factors, but I couldn't make 1/x^2 any closer that way.)
Since the a given numerical color value in the 0-1 range represents a brighter light in linear space than in sRGB, the attenuation cutoff is too high in linear mode, resulting in hard edges on the light tiles.
slipher commentedon Mar 17, 2026
#1929 has a hack to fix the issue shown above, but we should still look for a better equation for the linear blend regime.