Using two texture lookups to do 1-D^2 lighting is old hat see: http://www.ronfrazier.net/apparition/index.asp?appmain=research/advanced_per_p ixel_lighting.html

and http://www.shaderx.com/direct3d.net/tutorials/shader/shader5.html

If you want to do 1-D^2 lighting without texture lookups you can do this:

(In the following (x,y,z) is the vector from the light to the vertex interpolated across for each fragment and “r” is the radius of the light - see the above articles if unsure how to generate of calculate these)

When doing 1-D^2 attenuation you usually do:

// ((x/r),(y/r)) are the (s,t) values of the texture0 and (z/r) are the (s) values of the texture1

tex t0

tex t1

add r0, 1-t0, -t1.a ; 1.0 - (t0+ t1.a)

//Attenuate an existing color or bitmap

mul r0, c0, r0

This lookups two textures and combines the result.

However I find doing:

// ((x/r),(y/r),(z/r)) are the (s,t,r) values of the texture0

texcoord t0

//Calculate the attenuation

dp3_sat r1.rgba, t0_bx2,t0_bx2

//Attenuate a bitmap or color in r0

mul r0.rgb, r0, 1-r1

Can look just as good, uses no textures, 1 less texture instruction and the same amount or arthimatic instructions (if you have to multiply by a bitmap or color anyway) (There are some small banding artifacts but they are no worse than the texture lookup method - and on a bump-mapped surface you do not notice it)

Using this you can avoid extra textures that need to be bound when rendering and you may not need extra passes.

In the (ps1.4)ATI demos they allow any type of attenuation with a dependant 1D texture lookup -The theory goes something like this:

-First,get the d^2 value as above.(texture corrdinate then a dp3)

-Then use this value to do a dependant texture read into a 1D

attenuation map that has values pre-computed for all the distances.

Seperate diffuse and specular values can be encoded into the one lookup

texture with one in the rgb and the other in the alpha.

Doing this you can have really bizzare attenuation like sin(d), cos(d)

or any other equation that is limited to the 0…1 range

Here is some psudo PS1.4 code (not tested,purely for reference)

//Look up the texture coordinate data

texcrd r0.rgb,t0

//Get the distance squared

dp3 r5.rgb,r0_bx2,r0_bx2

phase

//Lookup the 1D attenuation texture

texld r1,r5

//Multiply diffuse attenuation by current diffuse

mul r0.rgb,r2,r1

//Multiply specular attenuation

+mul r0.a, r3.a,r1.a

In PS1.2 this would be (assuming you pass the appropiate biased

coordinates in t0 and un-biased coordinates in t1) (I have not tesed

this, so I do not know if t1 is clamped to 0…1 before the dp3, and if

it is, this technique will not work.-Needs to be clamped to -1…1 range)

texcoord t0

texdp3tex t1,t0_bx2

//Multiply diffuse attenuation by current diffuse

mul r0.rgb,r2,t1

//Multiply specular attenuation

+mul r0.a, r3.a,t1.a

In PS 1.1 we have to use a 2D attenuation lookup (only need 2 pixels

wide) as a 1D dependant texture lookup is not supported. (it dose not

really matter what value is in t2)

texcoord t0

texm3x2pad t1, t0_bx2

texm3x2tex t2, t0_bx2

//Multiply diffuse attenuation by current diffuse

mul r0.rgb,r2,t2

//Multiply specular attenuation

+mul r0.a, r3.a,t2.a

Of course if you needed attenuation outside the 0…1 range, you could also use x2 and x4 tricks on the texture lookup to get a 0…4 range.

Hope that helps (Of course if you are using ARB_fragment_Program the above is really mute as you can do all the calculations yourself)

[This message has been edited by sqrt[-1] (edited 03-05-2003).]

[This message has been edited by sqrt[-1] (edited 03-05-2003).]