# 9.7 - Light Attenuation¶

A basic property of light is that it loses its intensity the further it travels from its source. That is why Venus and Mercury are much hotter than the Earth and Mars is much colder. The intensity of light from the sun changes in proportion to the distance from the sun. The technical name for this is light attenuation.

This lesson explains how to include light attenuation in a light model.

## Light Attenuation¶

Light becomes weaker the further is travels from its source. In the physical
world the attenuation is proportional to 1/d^{2}, where `d` is
the distance between the light source and an object.
Using the function 1/d^{2} causes light to decrease very rapidly and so it is
common to make attenuation be proportional to 1/d. Notice that if `d`
is greater than 1, both equations calculate a fraction
between 0.0 and 1.0. Attenuation simply calculates a percentage of the
original light that is used to color a pixel.

The example *fragment shader* code below performs the following tasks:

- Calculate a vector from the fragment’s location to the light source.
- Calculate the length of the vector, which is the distance to the light source.
- Calculate the amount of attenuation. (For this example, the function
`10.0 / d`is used.) - Clamps the attenuation to be a percentage between 0% and 100%. (For the
equation
`10.0 / d`, any object closer than 10 units will receive full light, while objects more than 10 units away will receive less than full light. Obviously the value of 10 is arbitrary and would change based on a specific application’s needs.) - The final color of the fragment is a percentage of its calculated color.

```
to_light = u_Light_position - v_Vertex;
d = length( to_light );
attenuation = clamp( 10.0 / d, 0.0, 1.0);
// ...
color = attenuation * (ambient_color + diffuse_color + specular_color);
```

If you wanted an attenuation factor that could be changed during run-time,
you could make the constant in your attenuation equation be a `uniform`
variable that is assigned a value at run-time. However, using different
attenuation values for different models in a scene would be uncommon.

In the original OpenGL lighting model, the equation `1.0/(c1 + c2*d + c3*d^2)`
was used to give programmers control over attenuation. You could
set the values for c1, c2, and c3 to create a large number of possible
attenuation functions. Since programmable shaders were introduced, you
can implement the exact attenuation function that meets your
application’s needs.

In the literature you typically see an attenuation equation like
`10.0 / d` written with the proportional constant in the denominator like this,
`1.0 / 0.1*d`. You get the same results with either equation, but perhaps
one of the equations is more intuitive to you.

If you don’t want the attenuation to abruptly “kick in” at some distance from
the light source, you can add a one to the denominator to guarantee that
the denominator is always larger than the numerator. This eliminates the need
for the clamping function in the above example and provides a smooth attenuation
for any distance from the light source. You can experiment with various values
for the constants c1 and c2 in the plot of the attenuation function
`1.0/(1.0 + c1*d + c1*d^2)` below.

1.0 / (1.0 + 1.0*d + 1.0*d

^{2}

c1: 0.0 4.0

c2: 0.0 4.0

## Summary¶

Have you noticed that all lighting and color calculations are percentages!

## Glossary¶

- attenuation
- The decrease in intensity of electromagnetic wave energy as it travels away from its generating source.