https://www.geeks3d.com/hacklab/20180514/demo-wireframe-shader-opengl-3-2-and-opengl-es-3-1/#more-1349
gs:
#version 150 layout(triangles) in; layout(triangle_strip, max_vertices=3) out; uniform mat4 gxl3d_ModelViewProjectionMatrix; // GeeXLab auto uniform uniform vec2 WIN_SCALE; out vec3 dist; void main() { vec4 p0_3d = gl_in[0].gl_Position; vec4 p1_3d = gl_in[1].gl_Position; vec4 p2_3d = gl_in[2].gl_Position; // Compute the vertex position in the usual fashion. p0_3d = gxl3d_ModelViewProjectionMatrix * p0_3d; // 2D position vec2 p0 = p0_3d.xy / p0_3d.w; // Compute the vertex position in the usual fashion. p1_3d = gxl3d_ModelViewProjectionMatrix * p1_3d; // 2D position vec2 p1 = p1_3d.xy / p1_3d.w; // Compute the vertex position in the usual fashion. p2_3d = gxl3d_ModelViewProjectionMatrix * p2_3d; // 2D position vec2 p2 = p2_3d.xy / p2_3d.w; // Project p1 and p2 and compute the vectors v1 = p1-p0 // and v2 = p2-p0 vec2 v10 = WIN_SCALE*(p1 - p0); vec2 v20 = WIN_SCALE*(p2 - p0); // Compute 2D area of triangle. float area0 = abs(v10.x*v20.y - v10.y*v20.x); // Compute distance from vertex to line in 2D coords float h0 = area0/length(v10-v20); dist = vec3(h0, 0.0, 0.0); // Quick fix to defy perspective correction dist *= p0_3d.w; gl_Position = p0_3d; EmitVertex(); // Project p0 and p2 and compute the vectors v01 = p0-p1 // and v21 = p2-p1 vec2 v01 = WIN_SCALE*(p0 - p1); vec2 v21 = WIN_SCALE*(p2 - p1); // Compute 2D area of triangle. float area1 = abs(v01.x*v21.y - v01.y*v21.x); // Compute distance from vertex to line in 2D coords float h1 = area1/length(v01-v21); dist = vec3(0.0, h1, 0.0); // Quick fix to defy perspective correction dist *= p1_3d.w; gl_Position = p1_3d; EmitVertex(); // Project p0 and p1 and compute the vectors v02 = p0-p2 // and v12 = p1-p2 vec2 v02 = WIN_SCALE*(p0 - p2); vec2 v12 = WIN_SCALE*(p1 - p2); // Compute 2D area of triangle. float area2 = abs(v02.x*v12.y - v02.y*v12.x); // Compute distance from vertex to line in 2D coords float h2 = area2/length(v02-v12); dist = vec3(0.0, 0.0, h2); // Quick fix to defy perspective correction dist *= p2_3d.w; gl_Position = p2_3d; EmitVertex(); EndPrimitive(); }
fs:
#version 150 uniform vec3 WIRE_COL; uniform vec3 FILL_COL; in vec3 dist; out vec4 FragColor; void main() { // Undo perspective correction. //vec3 dist_vec = dist * gl_FragCoord.w; // Wireframe rendering is better like this: vec3 dist_vec = dist; // Compute the shortest distance to the edge float d = min(dist_vec[0], min(dist_vec[1], dist_vec[2])); // Compute line intensity and then fragment color float I = exp2(-2.0*d*d); FragColor.rgb = I*WIRE_COL + (1.0 - I)*FILL_COL; FragColor.a = 1.0; }
-----------------------------------------------------------------------------------------------------------------------------------------------------
http://www.imm.dtu.dk/~janba/Wireframe/
tri_vert_string.cpp
const char * tri_vert_string = "/* " " Input: The vertex position and vertex attributes p1_3d and p2_3d which " " are the positions of neighbouring vertices. " " " " Output: dist a vector of distances from the vertex to the three edges of " " the triangle. Clearly only one of these distance is non-zero. For vertex 0 " " in a triangle dist = (distance to opposite edge, 0, 0) on exit. The distance " " is multiplied by w. This is to negate perspective correction. " "*/ " "uniform vec2 WIN_SCALE; " "attribute vec4 p1_3d; " "attribute vec4 p2_3d; " " " "varying vec3 dist; " "void main(void) " "{ " " // We store the vertex id (0,1, or 2) in the w coord of the vertex " " // which then has to be restored to w=1. " " float swizz = gl_Vertex.w; " " vec4 pos = gl_Vertex; " " pos.w = 1.0; " " " " // Compute the vertex position in the usual fashion. " " gl_Position = gl_ModelViewProjectionMatrix * pos; " " " " // p0 is the 2D position of the current vertex. " " vec2 p0 = gl_Position.xy/gl_Position.w; " " " " // Project p1 and p2 and compute the vectors v1 = p1-p0 " " // and v2 = p2-p0 " " vec4 p1_3d_ = gl_ModelViewProjectionMatrix * p1_3d; " " vec2 v1 = WIN_SCALE*(p1_3d_.xy / p1_3d_.w - p0); " " " " vec4 p2_3d_ = gl_ModelViewProjectionMatrix * p2_3d; " " vec2 v2 = WIN_SCALE*(p2_3d_.xy / p2_3d_.w - p0); " " " " // Compute 2D area of triangle. " " float area2 = abs(v1.x*v2.y - v1.y * v2.x); " " " " // Compute distance from vertex to line in 2D coords " " float h = area2/length(v1-v2); " " " " // --- " " // The swizz variable tells us which of the three vertices " " // we are dealing with. The ugly comparisons would not be needed if " " // swizz was an int. " " " " if(swizz<0.1) " " dist = vec3(h,0,0); " " else if(swizz<1.1) " " dist = vec3(0,h,0); " " else " " dist = vec3(0,0,h); " " " " // ---- " " // Quick fix to defy perspective correction " " " " dist *= gl_Position.w; " "} ";
tri_frag_string.cpp
const char * tri_frag_string = " " "uniform vec3 WIRE_COL; " "uniform vec3 FILL_COL; " " " "varying vec3 dist; " " " "void main(void) " "{ " " // Undo perspective correction. " " vec3 dist_vec = dist * gl_FragCoord.w; " " " " // Compute the shortest distance to the edge " " float d =min(dist_vec[0],min(dist_vec[1],dist_vec[2])); " " " " // Compute line intensity and then fragment color " " float I = exp2(-2.0*d*d); " " gl_FragColor.xyz = I*WIRE_COL + (1.0 - I)*FILL_COL; " "} ";