Light Attenuation Over Distance

Direct3D uses the following formula to normalize the distance from a light source to a vertex into a value from 0.0 to 1.0, inclusive:

In the preceding formula, Dn is the normalized distance, R is the light's range, and D is the distance, in world space, from the light source to the vertex being lit. (When D is greater than R, the system assumes that no light reaches the vertex, and it moves to the next vertex to be lit.) A normalized distance is 1.0 at the light's source, and 0.0 at the light's range.

With the normalized distance in hand, Direct3D then applies the following formula to calculate light attenuation over distance for point lights and spotlights (directional and parallel point lights don't attenuate over distance):

In this attenuation formula, A is the calculated total attenuation and Dn is the normalized distance from the light source to the vertex. The dvAttenuation0, dvAttenuation1, and dvAttenuation2 values are the light's constant, linear, and quadratic attenuation factors as specified by the members of a light object's D3DLIGHT2 structure. (Not surprisingly, the corresponding structure members are dvAttenuation0, dvAttenuation1, and dvAttenuation2. In most cases, these attenuation factors are between 0.0 and 1.0, inclusive.)

The constant, linear and quadratic attenuation factors act as coefficients in the formula—you can produce a wide variety of attenuation curves by making simple adjustments to them. Most applications will set the linear attenuation factor to 1.0 and set the remaining factors to 0.0 to produce a light that steadily falls off over distance. Similarly, you could apply a constant attenuation factor of 1.0 by itself to make a light that doesn't attenuate (but will still be limited by range). The following illustration shows the three most common attenuation curves.

Note that using only quadratic attenuation often results in harsh transition between light and dark over distance. Each of the curves uses only one of the attenuation factors, but you are free to mix these values to create different attenuation effects.

The attenuation formula used by Direct3D computes an attenuation value that typically ranges from 1.0 at the light source to 0.0 at the maximum range of the light. (The result of the formula isn't normalized to fit between 0.0 and 1.0; attenuation outside that range is still considered valid, but will result in harsh or unpredictable lighting). The attenuation value is multiplied into the red, green and blue components of the light's color to scale the light's intensity as a factor of the distance light travels to a vertex. After computing the light attenuation, Direct3D also considers spotlight effects (if applicable), the angle that the light reflects from a surface, as well as the reflectance of the material that the vertex uses to come up with the diffuse and specular components for that vertex. For more information, see Spotlight Falloff Model and Reflectance Model.