what's mean of Attenuation0, Attenuation1, Attenuation2 of light?

Started by
2 comments, last by Bacterius 10 years, 2 months ago

i find the decription of the light's attenuation.

Atten = 1/(Attenuation0+Attenuation1*d + Attenuation2*d*d)

but how to use this Atten in shader?

if i use this value multiply diffuse color, the surface will be very dark.

is there any example shader codes about this topic?

Advertisement

It's just a formula so that instead of inverse square falloff (the usual) you can tweak the falloff to be the inverse of any (nonzero) second degree polynomial, which isn't physically correct but might make things look better, in particular by removing the singularity which makes stuff near the light stupidly bright. They have no physical basis (the only truly correct values are Attenuation0 = 0, Attenuation1 = 0, Attenuation2 = 1) and just give you or your artists a small artistic license.

To use it, you multiply the light's intensity by this attenuation value (Atten) using values of your liking for Attenuation0, Attenuation1, Attenuation2 (by playing around with them and seeing what looks good). Where "d" is the distance from the pixel to the light source.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

They have no physical basis (the only truly correct values are Attenuation0 = 0, Attenuation1 = 0, Attenuation2 = 1) and just give you or your artists a small artistic license.

If you're treating the light as a sphere with a radius, then the correct values are:
Attenuation0/constant = 1
Attenuation1/linear = 2/radius
Attenuation2/quadratic = 1/(radius^2)
or:
atten = 1/(1 + (2/r)*d + (1/r2)*d2)
which you can simplify to:
atten = 1/(d/r+1)2
or

atten = r2/(r+d)2

However, attenuations values inside the sphere (where d < r) are obviously bogus, and as dictated by physics, attenuation will never reach zero, so you need to fudge that a bit so you can perform sensible light culling.

Point lights (spheres with zero radius) don't make any physical sense (attenuation factor would almost reach 0% after almost 0m distance from the source) biggrin.png so Bacterius' values are an appropriate approximation (his values are the pure core of the inverse square law, with no other considerations), or you can use the above with radius=1, etc... which comes out as 1/(d+1)2, or a0=1, a1=2, a2=1.

if i use this value multiply diffuse color, the surface will be very dark

That's physics for you. With realistic attenuation (inverse-square law) your light sources have to be extremely bright. You end up with them being very, very bright right next to the light-source, but very quickly becoming dark. For this to look "right", you need to be rendering in HDR, and use a tone-mapper with a very large range (e.g. from 0 to 212) and a good logarithmic S-curve.

If you're not using HDR, it's common to just use linear attenuation, even though it's fake. e.g. a0=0, a1=1, a2=0 or a0=1, a1=2, a2=0, etc...

Basically, if you're not doing physically based rendering, you'd just tweak them so it looked ok wink.png


Actually if you're treating the light as a sphere with a radius, then the correct values are:
Attenuation0/constant = 1
Attenuation1/linear = 2/radius
Attenuation2/quadratic = 1/(radius^2)
or:
atten = 1/(1 + 2/rd + 1/r^2d^2)
which you can simplify to:
atten = 1(d/r+1)^2

However, attenuations values inside the sphere (where d < r) are obviously bogus, and as dictated by physics, attenuation will never reach zero, so you need to fudge that a bit so you can perform sensible light culling.

Yes, I was thinking of point lights, should have mentioned that (since they are so common). For spheres or area lights the treatment is different as they have an area.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

This topic is closed to new replies.

Advertisement