Skip to content

Instantly share code, notes, and snippets.

@tim37021
Created May 30, 2015 10:10
Show Gist options
  • Save tim37021/cdf47151d4064f572bc5 to your computer and use it in GitHub Desktop.
Save tim37021/cdf47151d4064f572bc5 to your computer and use it in GitHub Desktop.
Light culling geometry shader
#version 330
layout(points) in;
layout(triangle_strip, max_vertices=6) out;
in vec3 vColor[1];
out vec3 lightPos;
out vec3 lightColor;
uniform mat4 view;
// e: near
// a: aspect: height/width;
uniform float e=0.1, a=1.0;
void main(){
float rect[4]=float[](-1, -1, 1, 1);
// light sphere radius
float r=5.0;
vec3 l=(view*gl_in[0].gl_Position).xyz; vec3 l2=l*l; float r2=r*r;
float d=r2*l2.x-(l2.x+l2.z)*(r2-l2.z);
if(d>=0){
d=sqrt(d);
float nx1=(r*l.x+d)/(l2.x+l2.z), nx2=(r*l.x-d)/(l2.x+l2.z);
float nz1=(r-nx1*l.x)/l.z, nz2=(r-nx2*l.x)/l.z;
float pz1=(l2.x+l2.z-r2)/(l.z-(nz1/nx1)*l.x), pz2=(l2.x+l2.z-r2)/(l.z-(nz2/nx2)*l.x);
// Check if the light sphere is in front us(z<0)
if(pz1>=0&&pz2>=0) return;
if(pz1<0){
float fx=nz1/nx1/(tan(22.5)/a);
float px=-pz1*nz1/nx1;
if(px<l.x)
rect[0]=max(rect[0],fx);
else
rect[2]=min(rect[2],fx);
}
if(pz2<0){
float fx=nz2/nx2/(tan(22.5)/a);
float px=-pz2*nz2/nx2;
if(px<l.x)
rect[0]=max(rect[0],fx);
else
rect[2]=min(rect[2],fx);
}
}
d=r2*l2.y-(l2.y+l2.z)*(r2-l2.z);
if(d>=0){
d=sqrt(d);
float ny1=(r*l.y+d)/(l2.y+l2.z), ny2=(r*l.y-d)/(l2.y+l2.z);
float nz1=(r-ny1*l.y)/l.z, nz2=(r-ny2*l.y)/l.z;
float pz1=(l2.y+l2.z-r2)/(l.z-(nz1/ny1)*l.y), pz2=(l2.y+l2.z-r2)/(l.z-(nz2/ny2)*l.y);
if(pz1>=0&&pz2>=0) return;
if(pz1<0){
float fy=nz1/ny1/tan(22.5);
float py=-pz1*nz1/ny1;
if(py<l.y)
rect[1]=max(rect[1],fy);
else
rect[3]=min(rect[3],fy);
}
if(pz2<0){
float fy=nz2/ny2/tan(22.5);
float py=-pz2*nz2/ny2;
if(py<l.y)
rect[1]=max(rect[1],fy);
else
rect[3]=min(rect[3],fy);
}
}
// Prepare a quad for lighting
lightPos=vec3(gl_in[0].gl_Position);
lightColor=vColor[0];
gl_Position=vec4(rect[0], rect[1], 0, 1);
EmitVertex();
gl_Position=vec4(rect[2], rect[1], 0, 1);
EmitVertex();
gl_Position=vec4(rect[2], rect[3], 0, 1);
EmitVertex();
EndPrimitive();
gl_Position=vec4(rect[0], rect[1], 0, 1);
EmitVertex();
gl_Position=vec4(rect[2], rect[3], 0, 1);
EmitVertex();
gl_Position=vec4(rect[0], rect[3], 0, 1);
EmitVertex();
EndPrimitive();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment