Original Post
Ok, I am currently experimenting with deferred shading and one of the advantages of deferred shading is that many small lights (limited radius) can be rendered efficiently. But there is one problem: correct light attenuation never drops to zero. So I've been thinking about how the attenuation function could be modified to accommodate a limited radius, without this being too noticeable. I'll be assuming 1/(1+k*d^2) as the standard attenuation function, where k is the base [quadratic] attenuation coefficient, and d is the distance between the light, and the lit point. The simplest way to do this would be to just set the attenuation to 0 (as in multiply the lights intensity with 0) if the normal attenuation reaches a value of... let's say 0.01 (1% of original intensity). Obviously this would result in some quite nasty artifacts. And light radius would be constant as long as the attenuation coefficient isn't modified, but the attenuation coefficient should be constant, as it describes the attenuation in the medium (air, water or glass for example). A better way would probably be to multiply it with a function which passes through 0 at the desired radius and is 1 at a distance of 0. I think a function of the form 1-d^2/r^2 should work well enough. Using this and the same assumption that we want a cutoff at the radius where the attenuation should be 0.01 I got: (r^2-d^2)/(r^2+99*d^2) [result clamped to the range 0..1] I left out k here because this version simply sets a specified radius. Again, not particularly realistic, because we basically modify the attenuation in the medium, but ideal for artist-tunable light radius. But how should the radius of the light be determined? (This is an actual question, not a rhetorical one, despite my insanely long post/discourse ;-) ) One option I came up with is to base it on the lights intensity [Il] relative to the average intensity of the scene [Is], which should be computed for HDR scenes anyway, to be able to adjust exposure, so it's not really any extra work. (Obviously the last frame's intensity has to be used) So for a cutoff at 1% of the scene's intensity I got the following two formulae: r^2 = (100*Il-Is)/(k*Is) [if the result is negative, the light can simply be culled] att = (1-d^2/r^2)/(1+k*d^2) This can easily be adjusted to other cutoffs (the "100" in the first equation is simply 1/0.01) What do you think of this last type of attenuation? Would it work well enough? Or does anyone have any better suggestions? One potential problem might be that the feedback in the equation (via Is) might cause the average brightness of the scene to oscillate, but I think it is improbable that this would happen, as usually the intensity is averaged over time because an instant change in exposure wouldn't look particularly good. (Ok... that was one loooong post :-P)
