glsl线框网格模式wireframe
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 = "/* \n" " Input: The vertex position and vertex attributes p1_3d and p2_3d which \n" " are the positions of neighbouring vertices. \n" " \n" " Output: dist a vector of distances from the vertex to the three edges of \n" " the triangle. Clearly only one of these distance is non-zero. For vertex 0 \n" " in a triangle dist = (distance to opposite edge, 0, 0) on exit. The distance \n" " is multiplied by w. This is to negate perspective correction. \n" "*/ \n" "uniform vec2 WIN_SCALE; \n" "attribute vec4 p1_3d; \n" "attribute vec4 p2_3d; \n" " \n" "varying vec3 dist; \n" "void main(void) \n" "{ \n" " // We store the vertex id (0,1, or 2) in the w coord of the vertex \n" " // which then has to be restored to w=1. \n" " float swizz = gl_Vertex.w; \n" " vec4 pos = gl_Vertex; \n" " pos.w = 1.0; \n" " \n" " // Compute the vertex position in the usual fashion. \n" " gl_Position = gl_ModelViewProjectionMatrix * pos; \n" " \n" " // p0 is the 2D position of the current vertex. \n" " vec2 p0 = gl_Position.xy/gl_Position.w; \n" " \n" " // Project p1 and p2 and compute the vectors v1 = p1-p0 \n" " // and v2 = p2-p0 \n" " vec4 p1_3d_ = gl_ModelViewProjectionMatrix * p1_3d; \n" " vec2 v1 = WIN_SCALE*(p1_3d_.xy / p1_3d_.w - p0); \n" " \n" " vec4 p2_3d_ = gl_ModelViewProjectionMatrix * p2_3d; \n" " vec2 v2 = WIN_SCALE*(p2_3d_.xy / p2_3d_.w - p0); \n" " \n" " // Compute 2D area of triangle. \n" " float area2 = abs(v1.x*v2.y - v1.y * v2.x); \n" " \n" " // Compute distance from vertex to line in 2D coords \n" " float h = area2/length(v1-v2); \n" " \n" " // --- \n" " // The swizz variable tells us which of the three vertices \n" " // we are dealing with. The ugly comparisons would not be needed if \n" " // swizz was an int. \n" " \n" " if(swizz<0.1) \n" " dist = vec3(h,0,0); \n" " else if(swizz<1.1) \n" " dist = vec3(0,h,0); \n" " else \n" " dist = vec3(0,0,h); \n" " \n" " // ---- \n" " // Quick fix to defy perspective correction \n" " \n" " dist *= gl_Position.w; \n" "} \n";
tri_frag_string.cpp
const char * tri_frag_string = " \n" "uniform vec3 WIRE_COL; \n" "uniform vec3 FILL_COL; \n" " \n" "varying vec3 dist; \n" " \n" "void main(void) \n" "{ \n" " // Undo perspective correction. \n" " vec3 dist_vec = dist * gl_FragCoord.w; \n" " \n" " // Compute the shortest distance to the edge \n" " float d =min(dist_vec[0],min(dist_vec[1],dist_vec[2])); \n" " \n" " // Compute line intensity and then fragment color \n" " float I = exp2(-2.0*d*d); \n" " gl_FragColor.xyz = I*WIRE_COL + (1.0 - I)*FILL_COL; \n" "} \n";