Per pixel spotlight attenuation

I’m doing per-pixel lighting with 3 passes per light: attenuation, diffuse and specular

I’m writting attenuation to the alpha of the frame buffer, then blending the next two passes with it adding them at the same time to whatever is already in the frame buffer…

Everything works fine when using point lights. I use a 2D radial map in two texture units. Then I compute the texCoords in a vertex program and use them like so:

oTex0.x = texCoords.x
oTex0.y = texCoords.y
oTex1.x = texCoords.z
oTex1.y = 0.5

Then in the combiners, the final computed alpha is: 1-(tex0+tex1)

Know I want to create a spotlight kind of attenuation. Looking at the equation of a cone, I noticed that both x and y depend on z.

I changed tex1 a little bit (by creating a spotligth form, a cone), and instead of oTex1.y = 0.5, changed it to oTex1.y = texCoords.x. This resulted that in the Y direction, the light still attenuates like a sphere, but in the X direction works fine.

I can solve this (I think, I haven’t tried) with another texture unit…

But am I missing something? Does it really need 3 texture units to make a spotlight kind of attenuation? I’m doing something wrong?


I assume you have read both papers:


Yes I did read both…

Hi. I am also working on it, but only per pixel attenuation + per pixel diffuse lighting. I have read nutty’s tutorial about per pixel diffuse lighting, which uses NV_register_combiners and NV_vp. I would like to convert it to use ARB_dot3 and ARB_vp extensions.
But something is wrong. The triangles that are not facing the light are lit as if they had reversed normals (-nx, -ny, -nz). Also some tris, that are facing the light at some weird angle, are not lit. And when I move camera, the instensity is changing as if it was specular lightig.
I am stuck. Is it possible that NV_rc DOT_3 function performs the calculations different than the ARB one?
Or have You seen some sample apps that do the thing using ARB-only extensions?

Michal Krol

No, I actually didn’t find any demos of spotlighting (only the above one).

I’m actually using vp to calculate the texcoords and combiners to do the per pixel math.

I actually gave up. Will return to it some time later…

If register combiners + texture shaders are open to you, you could try looking at this thread

Look for the post by me and you shoud be able to do this in your attenuation pass.

texcoord t0 // The normalized distance from light
tex t1 // The spotlight cube map for attenuation

//Calculate the attenuation (D^2)
dp3_sat r1.a, t0_bx2,t0_bx2

//Attenuate a bitmap or color in r0
mul r0.a, t1, 1-r1 //cube map * (1- D^2)

//Write anything to r0.rgb