Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In OpenGL (and other systems) the distance attenuation factor for point lights is something like 1/(c+kd+sd^2), where d is the distance from the light abd c, k and s are constants.

I understand the sd^2 component which models the well known physically accurate "inverse square law" attenuation expected in reality.

I guess the constant c, usually one, is there to deal with very small values of d (and divide-by-zero defense perhaps?).

What role does the linear kd component have in the model, (by default k is zero in OpenGL). When would you use other values for k? I know that this is called the "linear attenuation" component, but what behavior does it simulate in the lighting model? It doesn't seem appear in any physical model of light that I'm aware of.

[EDIT]

It has been pointed out by David Gouveia that the linear factor might be used to help make the scene 'look' closer to what the developer/artist intended, or to better control the rate at which the light falls off. In which case my question becomes "does the linear attenuation factor have a physics counterpart or is it just used as a fudge factor to help control the quality of light in the scene?"

share|improve this question
    
I did not say that linear attenuation makes a scene look better or more realistic. What I said is that it might look better for your purposes. My raytracer illuminated a very small scene, and when comparing both models, the linear looked better. I don't need a physical reason to say it looked better - it just looked closer to the effect I wanted to achieve. Conversely, it's not that the inverse square law did not look realistic, it just fell off too quickly and contributed less to the scene illumination than what I needed. –  David Gouveia Dec 14 '11 at 14:29
    
Sorry David, I did not mean to misrepresent your answer. I've changed my edit above. –  Ken Dec 14 '11 at 14:54
    
Always good to remember that all lighting is a hack, pure and simple =) –  Patrick Hughes Dec 14 '11 at 20:17

8 Answers 8

up vote 19 down vote accepted

Light, from point-like sources, falls of with the square of the distance. That's physical reality.

Linear attenuation is often stated to appear superior. But this is only true when working in a non-linear colorspace. That is, if you don't have proper gamma correction active. The reason is quite simple.

If you're writing linear RGB values to a non-linear display without gamma correction, then your linear values will be mangled by the monitor's built-in gamma ramp. This effectively darkens the scene compared to what you actually intended.

Assuming a gamma of 2.2, your monitor will effectively raise all of the colors to the power of 2.2 when displaying them.

This is linear attenuation: 1/kd. This is linear attenuation with the monitor's gamma ramp applied: 1/(kd)^2.2. That's pretty close to a proper inverse-squared relationship.

But the actual inverse squared: 1/sd^2 becomes: 1/((s^2)(d^4.4)). This makes the light attenuation fall off much more sharply than expected.

In general, if you're using proper gamma correction (like rendering to an sRGB framebuffer), you shouldn't use linear attenuation. It won't look right. At all. And if you're not using gamma correction... what's wrong with you ;)

In any case, if you're trying to mimic reality, you want inverse-squared (and gamma correct). If you're not, then you can do whatever you need to for your scene.

share|improve this answer
3  
+1 I've known about gamma correct rendering for a while. I've known about quadratic and linear attenuation for a while. And this is the moment where I first realize the connection between the two. :-) –  David Gouveia Dec 14 '11 at 20:42
    
Any reason for the -1? –  Nicol Bolas Dec 15 '11 at 18:01

Flexibility.

Because you might want your lights to fall off linearly. It's there to give you that degree of control. It doesn't really need to be physically accurate (and the entire phong shading lighting equations are certainly not physically accurate either).

Sometimes the quadratic model will give out light too fast near the source and leave "white glares" in the nearby surfaces. By providing a linear and constant coefficients, you have the flexibility to adjust the results to your liking

For example, when I implemented a raytracer, I found out that the inverse square law made my point lights fall off too quickly. I changed to a clamped linear model (where each light had a minimum and maximum radius, with linear interpolation in between) and it just looked better.

Edit: Just found a nice resource explaining this.

share|improve this answer

Okay, I’m going to have a guess at it.

Preliminary observation

In OpenGL (and other systems) the distance attenuation factor for point lights is something like 1/(c+kd+sd^2), where d is the distance from the light and c, k and s are constants.

I understand the sd^2 component which models the well known physically accurate "inverse square law" attenuation expected in reality.

The curve for c+kd+sd^2 is a parabola, and so is the curve for sd^2; the difference is not as important as it may seem: they behave similarly at infinity, it’s just for small values that they’re different. Whatever k means, it’s only meaningful when close to the light.

Preliminary simplification

Since this is an attenuation factor you could as well set s == 1, or divide each constant by s in the expression, and divide your light source’s power by s. There is one parameter too many in the formula.

You end up with:

1/(c/s+(k/s)d+d^2)

Change of variables

… which is strictly equivalent to:

1/(A + D^2)

with A == c/s - k^2/(4s^2) and, more importantly, D == d + k/2s.

This 1/(A+D^2) really looks like the usual 1/(c+d^2), doesn’t it?

Conclusion

The k factor advances or delays the light attenuation so that it only starts at a radius of -k/2s (yes, it could also have "negative" radius, think of an imaginary point light inside an imaginary spherical mirror that would only let light out the second time). It appears that maths win again!

Edit: For a second I thought it was equivalent a spherical light, but it’s not. Most notably, it will not generate soft shadows.

Usefulness?

My guess is that this parameter can be used by an artist to make a light appear like it’s closer (or further away) to the object in terms of illumination, but without moving it. Since point lights generate hard shadows, it may be a requirement that the light remains at a specific position.

share|improve this answer

The linear attenuation coefficient is the physical counterpart of light travelling into a medium. Without attenuation, light seems to travel in perfect void. When rendering "realistic" scenes, you want the air to attenuate the intensity of light over distance, and this attenuation is linear.

share|improve this answer
    
I don't think that can be true. Light travelling through a medium would be attenuated by 1/d in the R coordinate, and still by 1/d^2 in the theta and phi spherical coordinates. What you describe is therefore a 1/d^3 attenuation of the light intensity. –  Sam Hocevar Dec 14 '11 at 17:29

The linear attenuation factor is there for cases where you might want to use linear attenuation for your lighting, but the key thing is - you don't have to use it (or any of the other attenuations factors, for that matter).

This allows you to tune your lighting to your own personal tastes. So just set any attenuation factor you don't want to 0 and the ones you do want to non-0 and it's done.

One specific example where you might want to use linear attenuation would be if the more mathematically correct inverse-square provides too fast a fall-off. Using linear you can get a result that can look more or less good enough (and with fewer lights in the scene); so you'd use 0 constant, 1 linear and 0 exponential.

It's interesting to note (but admittedly not relevant to this discussion) that point sprites in both OpenGL and D3D (and point parameters in OpenGL) use the same attenuation formula.

Also worth noting that OpenGL/D3D lighting is not strictly intended to be physically correct; it was never designed to be anything more than an acceptable approximation, and that should be borne in mind when querying anything relating to the way it works.

Of course, nowadays you'll most likely be using a shader so the old light formula is mainly of academic/historical interest only - you can write whatever light formula you want.

share|improve this answer
  • c is the constant attenuation value for the light source.
  • l is the linear attenuation. That's why it's multiplied by the distante to the light source.
  • s is the quadratic attenuation, so it's multiplied by the square of the distance.

There's some more info in this link.

share|improve this answer
    
Thanks, but my question is what is the role of the linear attenuation component in modelling light. I ask because it doesn't appear in any physics model of light that I'm aware of. The link you provide does NOT explain what the linear attenuation component is for. It just says; "this is linear attenuation", without any other explanation. –  Ken Dec 14 '11 at 12:55
    
Okay, I misinterpreted your question. Linear attenuation would be better observed in an infinite, one-dimensional light source (think a fluorescent tube), while quadratic models the behaviour of a spherical light source. So far I have found only one place where there is an explanation of the correspondence between the physical light model and the one used in computer graphics: imdoingitwrong.wordpress.com/2011/01/31/light-attenuation –  r2d2rigo Dec 14 '11 at 13:28

It's might derive from the fact that Z, in the words of the esteemed Eric Lengyel,

is nonlinear because perspective-correct rasterization requires linear interpolation of 1/z -- linear interpolation of z itself does not produce the correct results. The hardware must calculate 1/z at each vertex and interpolate it across a triangle, so it's convenient to just write that value to the depth buffer instead of performing an expensive division at every pixel to recover z.

The fact that you get more z precision closer to the near plane is just a side effect and has nothing to do with the motivation behind 1/z interpolation.

Depth buffer stores distances. Light uses distance for attenuation. It could be the relationship between the depth buffer and lighting implementations that necessitated this, though that would apply only if the lighting algorithm ran in screen space I suppose. Remember that it's better to always store a precalculated (or hardware calculated) inverse, than to have to perform division on the undivided value for each op per frame which needs it... and that tends to be a very large number of ops.

This is just a guess.

share|improve this answer
    
You might be onto something there. It may well have something to do with the space in which the lighting is calculated. But I don't think the depth buffer is part of it, as it stores 'pseudo-distance' from the eye (or front plane) to the object, not distance from the light to the object. It is the light distance which is used in lighting. –  Ken Dec 14 '11 at 16:01
    
@downvoter - care to comment, or just trolling? (to quote Jonathan) –  Nick Wiggill Dec 14 '11 at 22:49
    
Downvoting as well, the attenuation is calculated in eye space not normalized space -> perspective/z has nothing to do with this –  Oliver Zendel May 15 at 14:06

Just as an addenum: When using the openGL model to approximation a spherical light source all three coefficients make sense and are valid (not "to prevent overflows" or to have "artistical freedom"):

For a sphere with radius r we get:

1/(d/r+1)^2

this translates to

c = 1 k = 2/r s = (1/r^2)

(see http://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/).

Imho this approximation is better than using infinitesimally small point lights with no extend at all!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.