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).]