#pragma vertex uniform float lightsize; uniform vec3 lightpos; varying vec4 planeb, planel, planer, planef1, planef2, cone1, cone2; vec4 calcplane(vec3 norm, vec3 origin) { return vec4(norm, -dot(norm, origin)); } vec4 scaledplane(vec3 norm, vec3 origin, vec3 intersect) { return calcplane(norm, origin) / dot(norm, intersect); } #define v1 gl_MultiTexCoord0.xyz #define v2 gl_MultiTexCoord1.xyz #define up1 gl_MultiTexCoord2.xyz #define up2 gl_MultiTexCoord3.xyz void main(void) { gl_Position = ftransform(); vec3 v1dir = normalize(v1 - lightpos), v2dir = normalize(v2 - lightpos), v1fdir = normalize(v1 - lightpos + up1*lightsize), v2fdir = normalize(v2 - lightpos + up2*lightsize), edge = normalize(v2 - v1); planeb = calcplane(cross(v2dir, v1dir), v2); planel = scaledplane(cross(v1dir, v1fdir), v1, edge); planer = scaledplane(cross(v2fdir, v2dir), v2, -edge); vec3 forward1 = normalize(up1 + edge*max(-dot(up1, edge), 0.0)), forward2 = normalize(up2 - edge*max(dot(up2, edge), 0.0)); float scale1 = dot(forward1, planeb.xyz), scale2 = dot(forward2, planeb.xyz); planef1 = calcplane(v1dir * scale1 * lightsize / distance(v1, lightpos), v1); planef2 = calcplane(v2dir * scale2 * lightsize / distance(v2, lightpos), v2); cone1 = scale1 * scaledplane(cross(forward1, v1dir), v1, -edge); cone2 = scale2 * scaledplane(cross(v2dir, forward2), v2, edge); } #pragma fragment #extension GL_ARB_texture_rectangle : enable varying vec4 planeb, planel, planer, planef1, planef2, cone1, cone2; uniform sampler2DRect surfacetex; void main(void) { vec4 surface = texture2DRect(surfacetex, gl_FragCoord.xy); vec3 dist = vec3(dot(surface, planel), dot(surface, planer), dot(surface, planeb)); if(any(lessThan(dist, 0.0))) discard; float fdist1 = dot(surface, planef1), fdist2 = dot(surface, planef2); if(max(fdist1, fdist2) - dist.z < 0.0) discard; dist.x = dot(surface, cone1); dist.y = dot(surface, cone2); vec2 side = max(-dist.xy, 0.0); float radius = mix(fdist1, fdist2, side.x / (side.x + side.y)); gl_FragColor.rgb = vec3(length(max(dist.xyz, 0.0) / radius)); }