Created
May 30, 2015 10:10
-
-
Save tim37021/cdf47151d4064f572bc5 to your computer and use it in GitHub Desktop.
Light culling geometry shader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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