Light Deacy

Ok

for Lamp lights, if I press ‘Quad’ the ratio of decay of the energy is proportional to the inverse of the distance, square. This is correct and physically appealing.

But if I do NOT press quad, how does the light decay? Linearly?

Thanx in advance

Stefano

it depends if you turned Sphere ON or OFF.

If it’s ON, then it’s linearly. Otherwise, it doesn’t decrease with distance.

Same applies for Quad too. If Sphere is off, the formula is more or less E = E0 / r**2 but when it’s on, it’s more like E = E0 (size - r) ** 2.

AFAIK of course.

Martin

Sphere button… I forgot of that :slight_smile:

But even with Sphere OFF I’d say it decreases.

For a couple of tests I made I’d say that with Sphere ON the light is 0 at given distance and follows a linear/quadratic law inside.

If Sphere is OFF the light is 1 (probably the energy) at the give Distance
and follows the linear / quadratic law everywhere.

Thanx Martin, anyone has more tips?

Stefano

for Lamp lights, if I press ‘Quad’ the ratio of decay of the energy is proportional to the inverse of the distance, square. This is correct and physically appealing.

But if I do NOT press quad, how does the light decay? Linearly?

I’ll check the source the next chance I get (if I remember to do so :-? ).

Thank you a LOT I need that for the Doc… and found no clear explanation so far :slight_smile:

Stefano

Cessen,

before you spend too much time in the sources,

looking in the 2.0 guide in the Button section I found
the formulas D/(D+a) and D/(D+a^2) which make sense but
there is no hint on how the ‘Sphere’ button change this :slight_smile:

Stefano

There is not that much time to spend, it is a very small piece of code in pixelshading.c

As far as I can see, it is something like this:

Quad:
intensity = (Dist / (Dist + quad1*lampdistance)) * (Dist^2 / ((Dist^2 + quad2 * lampdistance^2)))

this might be a mistake (or not, I’m not sure), something like 1/(a + bdistance + cdistance^2) might have been the intention.

Regular lamp:
intensity = Dist / (Dist + lampdistance)

Sphere:
intensity = (Dist - lampdistance) / (Dist + lampdistance)
ignoring negative values

Dist is the value of the ‘Dist’ button, and lampdistance is the actual lampdistance to the current point to be shaded.

The relevant piece of code is this, from pixelshading.c:


if(lar->mode & LA_QUAD) {
	t= 1.0;
	if(lar->ld1>0.0)
		t= lar->dist/(lar->dist+lar->ld1*ld);
	if(lar->ld2>0.0)
		t*= lar->distkw/(lar->distkw+lar->ld2*ld*ld);

	lampdist= t;
}
else {
	lampdist= (lar->dist/(lar->dist+ld));
}

if(lar->mode & LA_SPHERE) {
	t= lar->dist - ld;
	if(t<0.0) continue;
				
	t/= lar->dist;
	lampdist*= (t);
}

Of course, Cessen would be able to really explain all this, I have no clue about what I just wrote above really…

Thanx a lot…

sob…

I’ll have to rewrite that section almost entirely…

This applies only to Lamp & Spots, right?

Stefano

Yes, sun & hemi are just directional lights with no falloff, hemi is like sun but uses the full normal/lightvector dotproduct result instead of ignoring the negative values as for regular lighting, it just does 0.5+(N.L)*0.5, a trick I used myself very long ago in my first landscape engine.

So, to summarize:

DIST is the distance to which the light will remain at full strength, beyond which it will attenuate.

Is there any way to visualize “dist?” On everything but “Lamp” I can see the effect on the dotted line that extends down from the lamp, but on just plain ol’ “Lamp” there is no apparent affect.

Did I miss someone say “on just ‘Lamp’ there is no attenuation, so DIST is meaningless?”

Thanks,

-Bischofftep

Well, it’s not really a “trick”. Rather, it’s the analytic solution to solving the integral of light coming in from a 180-degree range of directions (i.e. a huge hemisphere… hence why it is called “hemi”). Of course, the integral assumes a Lambertian surface material (i.e. cosine falloff).

I’ve looked at the code now, and I have figured out the following:

If the lamp is neither QUAD nor SPHERE, then the falloff uses the following function:

f(d) = n/(n+d)

where n is the “dist” setting of the lamp, and d is the distance from the lamp to the point being lit.
Note that this is the equivilant of a “1/x” falloff, except that it has been tweaked to make it customizable, and to make it so that whenever d=0, f(d)=1.

If the lamp is SPHERE, then it uses:

f(d) = (1-(d/n))^2

Where n is the “dist” setting, and d is the distance from the lamp to the point being lit. The intensity is clipped to zero if it goes below zero.
Note that this is the same as calculating a linear fall-off, and then squaring it (not the same as an inverse-square falloff).

If the lamp is QUAD, then it uses:


           n             n^2
f(d) = ---------- * --------------
       n + (a*d)   n^2 + (b*d^2)

where n is the “dist” setting, a is the “quad1” setting, b is the “quad2” setting, and d is the distance from the lamp to the point being lit.
The problem that I see with this equation, though, is that if you work with it a bit, you get:


                    n^3
f(d) = -----------------------------
       abd^3 + bnd^2 + a(n^2)d + n^3

which is inverse cubic rather than inverse quadratic. Of course, you can get inverse quadratic by having a=0, but then you can’t have the linear component of the quadratic equation.
The equation should be something like this (though perhaps a little different):


            n^2
f(d) = ---------------
       bnd^2 + a(n^2)d

I suspect that someone was very tired when they were working out the math for the quad-lamp falloff. :wink:

Anyway, I hope this helps you out, S68. :slight_smile:

It was definitely a ‘trick’ when I used it at the time, I have no clue about integral’s (well, not back then anyway) or whatever, it was just a hack I came up with that I found to improve the lighting in that situation.

Anway, excellent and clear explanation, I knew you would do that… :wink:

Thanx Cessen :slight_smile:

I got the Linear and Quad decay now.What puzzles me is still the ‘sphere’ option.

From the code fragment eeshlo posted I got the (wrong ?) impression thet the Sphere light decay had just a multiplicative factor (n-r)/(n+r). If I got it right then there would still be difference between Linear and Quad Decay for a Sphere lamp, but if Cessen is right then there wouldbe no difference and Sphere would override any other setting.

Did I got this right?

Thanx you again

Stefano

Well, I really don’t want to contradict Cessen, but as far as I can see it was correct. The code flow is as follows, if the lamp is not quad, first the decay for a regular lamp is calculated:


Dist / (Dist + lampdistance)

then if ‘sphere’ mode is set, this is further multiplied by (unless the result is negative):


(Dist - lampdistance) / Dist

I just rewrote this as:


(Dist - lampdistance) / (Dist + lampdistance)

Don’t forget that it is also possible to use ‘Quad’ and ‘Sphere’ together in which case you get:


quad_intensity * (Dist - lampdistance) / Dist

I don’t really feel like expanding that to the full equation… :wink:

But again, since I have to get by with less than highschool maths, I certainly would trust Cessen to really know what he is talking about, so let’s just wait what The CG Theory Guru :stuck_out_tongue: has to say about this.