Dynamic lighting with a 3D texture?

I have a system implemented whereby my world BSP faces get lit with a “decal” light. A circular gradient texture is mapped onto the face and drawn with an additive blend. The results are asthetically excellent, but it is very slow to go through all the BSP faces in a large map and draw them one-by-one.

If I can figure out a way to set the texture and mapping up where it doesn’t depend on the orientation of the face, I could draw the whole BSP area at once, which would be much faster. There are two ways I can think of that might work.

The first would be to just use a shader that maps each vertex coordinate based on distance from the light position, and use a 1D linear gradient texture. However, I could see this causing visual errors.

The other option is to maybe use a 3D texture, auto-map the S, T, and R axes, and have the 3D texture represent a spherical gradient. I have never dealt with 3D textures (other than cubemaps) and don’t have a clue whether this is something they can be used for.

Is it possible to use a 3D texture this way? If so, please explain how.

it is possible to use a 3d texture this way, but it is better to use two gradient textures: a 2d texture encoding x and y, and a 1d texture encoding z. this will save some memory and if you use larger textures you will get better results without much extra memory.
another way is to use fragment shaders, so you can calculate the attenuation per pixel without the need for any gradient textures at all

I thought about a fragment shader, but thought it might be slow to calculate a distance between the camera and every single fragment.

I think the xy and gradient texture is a good idea, but I think it actually needs to use the same 2D circular gradient on all three texture axes to get a sphere of light. This will not be a problem.

This is some information about my results, for anyone who might read this thread in the future:

I found that using a 3D gradient texture, I could use a very low-res spherical gradient. I am using a 16x16x16 GL_LUMINANCE texture right now, which is a mere 4096 bytes. In comparison, a 512x512 RGB texture would be 786432 bytes.

The gradient doesn’t look blocky or low-res at all, probably because it is a gradient texture by nature, so the texture smoothing makes it look about the same as if it was 512x512x512. I probably wouldn’t use texture compression on this texture, since it tends to make gradients look ugly.

So, it works great!