#version 410 layout( triangles_adjacency ) in; layout( triangle_strip, max_vertices = 18 ) out; in vec3 VPosition[]; in vec3 VNormal[]; uniform mat4 ViewMatrix; uniform mat4 ProjMatrix; struct LightInfo { vec3 Ldir; vec3 La; vec3 Ld; vec3 Ls; }; uniform LightInfo Light; bool facesLight( vec3 a, vec3 b, vec3 c, vec3 light ) { vec3 n = cross( b - a, c - a ); return dot(n, light) < 0; } void emitEdgeQuad( vec3 a, vec3 b, vec3 light ) { gl_Position = ProjMatrix * vec4(a, 1); EmitVertex(); gl_Position = ProjMatrix * vec4(light, 0); EmitVertex(); gl_Position = ProjMatrix * vec4(b, 1); EmitVertex(); gl_Position = ProjMatrix * vec4(light, 0); EmitVertex(); EndPrimitive(); } void main() { vec3 light = vec3( ViewMatrix*vec4(Light.Ldir, 0.0) ); // If the main triangle faces the light, check each adjacent // triangle. If an adjacent triangle does not face the light // we output a sihlouette edge quad for the corresponding edge. if( facesLight(VPosition[0], VPosition[2], VPosition[4], light) ) { if( ! facesLight(VPosition[0],VPosition[1],VPosition[2], light) ) emitEdgeQuad(VPosition[0],VPosition[2], light); if( ! facesLight(VPosition[2],VPosition[3],VPosition[4], light) ) emitEdgeQuad(VPosition[2],VPosition[4], light); if( ! facesLight(VPosition[4],VPosition[5],VPosition[0], light) ) emitEdgeQuad(VPosition[4],VPosition[0], light); } }