It’s been used in games, via occlusion-queries. (thus for few lamp-objects)

The depth-test in a vtxshader is the correct way to go for many many lamps, imho. Each vertex of the billboard quad will do the same check (if you can’t use geom. shaders) and reset its gl_position to a fixed value (i.e vec4(0,0,0,1) if the center-point is outside of frustum behind zbuffer (to generate degenerate triangles).

```
//-----[ attributes, constant for the 4 vertices ]-----------------[
in vec4 inPos; // center-position of lamp
in float inLampRadius;
//-----------------------------------------------------------------/
//----[ attributes, different for each of the 4 vtces ]-------[
in vec2 inCorner; // = vec2(1,1) or vec2(0,1) or vec2(0,0) or vec2(1,0)
//------------------------------------------------------------/
out vec2 varTexCoord0;
uniform mat4 u_MVP; // modelviewprojection
uniform vec4 u_FrustumPlanes[6];
uniform sampler2D texDepthBuffer;
void main(){
bool isInFrustum=true;
//-------[ check if in frustum ]---------[
for(int i=0;i<6;i++){
if(dot(u_FrustumPlanes[i],inPos) < -inLampRadius){ // verify this yourself, I'm typing by memory...
isInFrustum=false;
}
}
//---------------------------------------/
if(!isInFrustum){
gl_Position = vec4(0,0,0,1);
return;
}
vec4 pos = u_MVP * inPos;
//-----------[ zbuffer check ]---------------------[
vec3 texPos;
texPos.xyz = (pos.xyz/pos.w)*0.5+0.5; // in [0;1] screenspace
float depthFromZBuffer = texture2D(texDepthBuffer,texPos.xy).x;
if(depthFromZBuffer< texPos.z){ // behind zbuffer
gl_Position = vec4(0,0,0,1);
return;
}
//-------------------------------------------------/
//-----[ yay, visible, so construct position and texcoord ]-------------------------[
gl_Position = pos + vec4(inCorner,0,0); // construct different corner position
varTexCoord0 = inCorner*0.5+0.5; // construct [0;1] texcooord
//----------------------------------------------------------------------------------/
}
```

Of course, don’t forget to disable depth-writes if you’re drawing to the same single-sampled FBO; or use a resolved depth-tex from the multisampled FBO.

P.S Also disable depth-test, to achieve precisely what you wanted.