# Light Attenuation Formula Derivation

I understand that when sampling the brightness of a given point on the surface, a certain cutoff needs to be taken into consideration.

Other words, when the light is further away, the intensity decreases.

I came across the following formula that is used to compute the aforementioned:

attenuation = 1.0 / (1.0 + a * dist + b * dist * dist)

However, I have not been able to find out why and how this formula is derived.

From the formula what I can understand is that as the distance get larger, the result will become smaller; but how it is derived is beyond me.

If distance takes an important role in the above formula, which helps determine the intensity, could we simply ignore a and b from the formula and simply use:

attenuation = 1.0 / (1.0 + dist)

?

Does anyone know how the formula is derived and the importance the values a and b play within the formula?

Thanks.

In real physics, light (like many other influences) falls off as the inverse square of distance from the source.

You can visualize this by imagining a lightbulb giving off one instantaneous flash - the photons of light released form a hollow sphere expanding away from the bulb like a ripple in a pond. As the sphere expands, no new photons or energy are added to it, so the same amount of brightness is spread across a wider and wider area. If we sample the brightness at one distance (say 1 metre), then wait until the sphere has grown twice as big, its surface area is now four times as large, so the brightness at any one spot will be one quarter of what we saw before. At triple the distance, the sphere has nine times the area, so the brightness will be one ninth, etc.

(This is simplified, of course. Ask on the Physics StackExchange if you want all the messy details of waves and quantum stuff etc...)

So, by this theoretical line of thinking, attenuation = 1.0 / dist * dist

(Where our "reference brightness" for the light is measured one unit away, where attenuation = 1)

Okay, now we enter the practical world of cheats that make sense for computer hardware and help us do our jobs as game developers.

Firstly: the formula above has a big problem: it has a singularity when distance is zero!

Usually in physics we'd only model a light source as an infinitely small point like this if we're enough distance away that the approximation won't matter, but in games our point/spot lights are often literally infinitely small points, and if we're not careful, geometry in our scene could get quite close to them or even cross them, making the math become very ill-behaved (eg. as your firefly lands on a leaf, it makes a bright spot brighter than the Sun)

So, we fix that by adding an offset: attenuation = 1.0 / (1.0 + dist * dist)

Now even if distance approaches zero, attenuation will never exceed 1.0, and so the light will never shine brighter than the reference brightness we've set.

(Our reference brightness is now measured at the position of the light itself, rather than one unit away. If we want the same behaviour at the 1 unit mark, we'll need to double the reference brightness compared to the previous/physical version of the formula)

Great. But it's not very customizable.

When we're lighting a game, we often care more about control to be able to get the look we want, rather than slavish obedience to physical laws. So we add a coefficient that lets us make the falloff a little sharper or a little shallower. In fact, let's add two coefficients so we can shape the falloff curve:

Now we get the familiar 1.0 / (1.0 + a * dist + b * dist * dist)

So, why add that linear term? This answer suggests that it was useful in older games when rendering without proper gamma correction. The display gamma plus an inverse square falloff would combine to make the light falloff look too sharp. By using an inverse linear falloff (a ~ 1, b ~ 0) we can cheat it to look more correct, letting the display gamma do the squaring. In modern games though, we'd prefer to do proper gamma correction (in addition to things like HDR tonemapping) to make sure our colours look right, so nowadays we'd usually only play with these coefficients for stylistic reasons.

tl;dr: a = 0, b = 1 is a pretty safe bet unless you want a more stylistic effect.

• Apologies for late reply; but let's say if we had a light source whose distance is so immeasurably large (such as the sun), could we, then, simply apply 1 / 1 + distance without applying the inverse square law? I recall reading that from somewhere, but I couldn't find it. Thanks. – Unheilig Oct 26 '16 at 23:50
• At a very large distance, the relative falloff (ie. from the closest thing in your scene to the furthest) is just about flat, so you could even set a = b = 0 and have no falloff, so you can control the brightness directly. That's why the sun is usually modelled as a directional light with no falloff: it's so far away its rays are effectively parallel and equal in brightness as we move around on human or planetary scales. – DMGregory Oct 27 '16 at 0:04
• Even at interplanetary scales, I'd be inclined to model a star's light as a directional light on each planet/neighbourhood, to better control shadowcasting for eclipses etc. – DMGregory Oct 27 '16 at 0:06
• I see. I really hope I can find that article I read regarding the 1 / 1 + distance formula in which it mentions the usage in that particular case. But let's forget about that: would you ever use the aforementioned formula (1 / 1 + distance); if so, in which scenario would you use it (this may help me understand)? Thank you. – Unheilig Oct 27 '16 at 0:11
• Check the post linked above for some ideas there. One answer says it can partly compensate for lack of gamma correction. Other answers suggest it can be used to model light being filtered by fog, or that you can use it to model a larger spherical light (though it won't give you soft shadows on its own), or that you can use it to advance/delay the attenuation effect. The takeaway I get is that the linear term lets us control the lighting in many more ways than we could without it. – DMGregory Oct 27 '16 at 0:22

This attenuation formula lets you express the light falloff from a spherical area light.

\begin{align} f_{att} &= \frac 1 {\left( \frac d r + 1\right)^2}\\ & = \frac 1 {1 + \frac 2 r d + \frac 1 {r^2} d^2}\\ \\ a &= \frac 2 r, \quad b = \frac 1 {r^2} \end{align}

See the full article for more details on clipping the range of effect for these lights, and shader code.