# Perpixel Attenuation

What if I want to attenuate light intensity per pixel using only dot3 and multitexturing?
Is it correct to attenuate light per vertex and interpolate the result; e.g, use glColor to assign light intensity and let OpenGL interpolate the color values assigned per vertex to simulate attenuation.
Thanks.

This will work, if your tesselation is reasonable, and if the distribution of vertices along your model is homogenous, otherwise you’ll get the usual vertex-lighting artifacts, especially with small attenuation ranges.

Suggestions:
Use a radial gradient 2D texture, and a second, 1D texture that represents one horizontal line from the middle of the 2D texture. Project the 2D texture with texgen, e.g. in the XY plane (X=s, Y=t). Project the 1D texture in another texture unit so that Z=s. Configure combiners so that T = T0*T1 and modulate your light intensity with T

Simpler, and only using one Texture unit, if you have a GF3 and higher, is using a 3D texture as attenuation map.

And then you may be able to compute the attenuation factor in the register combiners (not sure, especially not if you’re doing per-pixel dot products anyway that may be difficult).

The 2D*1D method has the disadvantage of tying up 2 texture units, but works on TNT2 and up. 3D texture uses more memory, only works on GF3+, but also only uses one texture unit. Both texture based techniques have the advantage of being able to pretty much do anything you want with the falloff (just paint it into the texture )

Another way to only use one TMU is to set the XY radial map to say tex0. Then put the intensity scaled tangent space light vector in col0 and do the following ops:

Atten = 1-(XY+Z)

So in nvparse code that would look like this:

spare0 = unsigned_invert( tex0 ) + -expand( col0 ) * expand( col0 );

Supposedly this next code clip should work but it wouldnt for me at one time, maybe ill try it again sometime.

discard = unsigned_invert( tex0 ) * unsigned_invert( zero );
discard = -expand( col0 ) * expand( col0 );
spare0 = sum();

Hope that helps some.

-SirKnight

[This message has been edited by SirKnight (edited 07-13-2002).]