/** * 2D Quadratic Bezier thick line drawing */ #define MID_VERTEX 57 /* u is position along the curve, defining the tangent space. * v is "signed" distance (compressed to [0..1] range) from the pos in expand direction */ in vec2 uv; in vec2 pos; /* verts position in the curve tangent space */ in vec2 expand; #ifdef USE_INSTANCE /* Instance attrs. */ in vec2 P0; in vec2 P1; in vec2 P2; in vec2 P3; in ivec4 colid_doarrow; uniform vec4 colors[6]; # define colStart colors[colid_doarrow[0]] # define colEnd colors[colid_doarrow[1]] # define colShadow colors[colid_doarrow[2]] # define doArrow (colid_doarrow[3] != 0) #else /* Single curve drawcall, use uniform. */ uniform vec2 bezierPts[4]; # define P0 bezierPts[0] # define P1 bezierPts[1] # define P2 bezierPts[2] # define P3 bezierPts[3] uniform vec4 colors[3]; uniform bool doArrow; # define colShadow colors[0] # define colStart colors[1] # define colEnd colors[2] #endif uniform float expandSize; uniform float arrowSize; uniform mat4 ModelViewProjectionMatrix; out float colorGradient; out vec4 finalColor; void main(void) { float t = uv.x; float t2 = t * t; float t2_3 = 3.0 * t2; float one_minus_t = 1.0 - t; float one_minus_t2 = one_minus_t * one_minus_t; float one_minus_t2_3 = 3.0 * one_minus_t2; vec2 point = (P0 * one_minus_t2 * one_minus_t + P1 * one_minus_t2_3 * t + P2 * t2_3 * one_minus_t + P3 * t2 * t); vec2 tangent = ((P1 - P0) * one_minus_t2_3 + (P2 - P1) * 6.0 * (t - t2) + (P3 - P2) * t2_3); /* tangent space at t */ tangent = normalize(tangent); vec2 normal = tangent.yx * vec2(-1.0, 1.0); /* Position vertex on the curve tangent space */ point += (pos.x * tangent + pos.y * normal) * arrowSize; gl_Position = ModelViewProjectionMatrix * vec4(point, 0.0, 1.0); vec2 exp_axis = expand.x * tangent + expand.y * normal; /* rotate & scale the expand axis */ exp_axis = ModelViewProjectionMatrix[0].xy * exp_axis.xx + ModelViewProjectionMatrix[1].xy * exp_axis.yy; float expand_dist = (uv.y * 2.0 - 1.0); colorGradient = expand_dist; if (gl_VertexID < MID_VERTEX) { /* Shadow pass */ finalColor = colShadow; } else { /* Second pass */ finalColor = mix(colStart, colEnd, uv.x); expand_dist *= 0.5; } /* Expand into a line */ gl_Position.xy += exp_axis * expandSize * expand_dist; /* if arrow */ if (expand.y != 1.0 && !doArrow) { gl_Position.xy *= 0.0; } }