#version 450 core layout(points) in; //layout(triangle_strip, max_vertices = 18) out; layout(triangle_strip, max_vertices = 9) out; layout(std140, binding = 0) uniform TheMat { mat4 theMat; }; layout(location=0) uniform vec3 lightPos; layout(location=1) uniform float rad; //float rad = rad; // Preprocessed to include ../functions.glsl float closestPointOnLineParam (vec2 a, vec2 b, vec2 p) { return dot(p - a,b-a) / dot(b-a,b-a); } vec2 closestPointOnSeg (vec2 a,vec2 b, vec2 p) { float x = closestPointOnLineParam(a,b,p); if (x < 0) { return a; } else{ if (x > 1) { return b; } { return a + (x * (b- a));} } } // End include 2023-03-13 15:33:44.438312149 UTC vec2 closestPointOnLine (vec2 a,vec2 b, vec2 p) { float x = closestPointOnLineParam(a,b,p); return a + (x * (b- a)); } vec2 invclosestPointOnLine (vec2 a,vec2 b, vec2 p) { float x = dot (p-a,p-a)/ dot(p-a,b-a); return a + x*(b- a); } vec2 shift(vec2 p) { return vec2(lightPos.xy + (rad * normalize(p - lightPos.xy))); } float detV(vec2 p, vec2 q) { return p.x*q.y - p.y*q.x; } float isLHS(vec2 p, vec2 q) { return sign(-detV(p,q)); } // the following does NOT check for division by zero: do not reuse this unless // you are certain this cannot happen vec2 intersectLL(vec2 p1,vec2 p2,vec2 q1,vec2 q2){ float den = detV (p1-p2,q1-q2); float t = detV (p1-q1,q1-q2); return p1 + (t/den)*(p2-p1); } // constructs a "bridge" shape void main() { vec2 p1 = gl_in[0].gl_Position.xy; vec2 p2 = gl_in[0].gl_Position.zw; vec2 closepoint = closestPointOnSeg(p1,p2,lightPos.xy); if (isLHS(p1 - lightPos.xy, p2 - lightPos.xy) < 0 && distance(closepoint,lightPos.xy) < rad) { vec2 xxxy = p1 + (0.25 * (p2 -p1)); vec2 xt = shift(xxxy); vec2 xo = invclosestPointOnLine(lightPos.xy,p1,xt); vec2 xyyy = p1 + (0.75 * (p2 -p1)); vec2 yt = shift(xyyy); vec2 yo = invclosestPointOnLine(lightPos.xy,p2,yt); vec2 xoo = (distance(xo, lightPos.xy) < distance(p1, lightPos.xy) || distance(p1,lightPos.xy)>rad ? p1 : xo); vec2 yoo = (distance(yo, lightPos.xy) < distance(p2, lightPos.xy) || distance(p2,lightPos.xy)>rad ? p2 : yo); vec2 mo = intersectLL(xoo,xt,yoo,yt); vec2 closeshift = (rad * normalize(closepoint - lightPos.xy)) + lightPos.xy - closepoint; vec2 shifto = (rad * normalize(closepoint - lightPos.xy)) + closepoint; vec2 p1o = vec2( distance(p1,lightPos.xy) > rad ? p1 : shift(p1) ); //vec2 p1o = xoo; vec2 p2o = vec2( distance(p2,lightPos.xy) > rad ? p2 : shift(p2) ); //vec2 p2o = yoo; gl_Position = theMat * vec4(p1o,-500,1); EmitVertex(); gl_Position = theMat * vec4(p1,-500,1); EmitVertex(); gl_Position = theMat * vec4(p1o,100,1); EmitVertex(); gl_Position = theMat * vec4(p1,100,1); EmitVertex(); gl_Position = theMat * vec4(shifto,100,1); EmitVertex(); //gl_Position = theMat * vec4(xt,100,1); EmitVertex(); //gl_Position = theMat * vec4(mo,100,1); EmitVertex(); gl_Position = theMat * vec4(p2,100,1); EmitVertex(); gl_Position = theMat * vec4(p2o,100,1); EmitVertex(); gl_Position = theMat * vec4(p2,-500,1); EmitVertex(); gl_Position = theMat * vec4(p2o,-500,1); EmitVertex(); EndPrimitive(); // be carefull with the winding... EndPrimitive(); } else { } }