Spaces:
Sleeping
Sleeping
| // floor(127 / 2) == 63.0 | |
| // the maximum allowed miter limit is 2.0 at the moment. the extrude normal is | |
| // stored in a byte (-128..127). we scale regular normals up to length 63, but | |
| // there are also "special" normals that have a bigger length (of up to 126 in | |
| // this case). | |
| // #define scale 63.0 | |
| attribute vec2 a_pos_normal; | |
| attribute vec4 a_data; | |
| uniform mat4 u_matrix; | |
| uniform mediump float u_ratio; | |
| uniform vec2 u_units_to_pixels; | |
| uniform lowp float u_device_pixel_ratio; | |
| varying vec2 v_normal; | |
| varying vec2 v_width2; | |
| varying float v_gamma_scale; | |
| varying highp float v_linesofar; | |
| void main() { | |
| // the distance over which the line edge fades out. | |
| // Retina devices need a smaller distance to avoid aliasing. | |
| float ANTIALIASING = 1.0 / u_device_pixel_ratio / 2.0; | |
| vec2 a_extrude = a_data.xy - 128.0; | |
| float a_direction = mod(a_data.z, 4.0) - 1.0; | |
| v_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0; | |
| vec2 pos = floor(a_pos_normal * 0.5); | |
| // x is 1 if it's a round cap, 0 otherwise | |
| // y is 1 if the normal points up, and -1 if it points down | |
| // We store these in the least significant bit of a_pos_normal | |
| mediump vec2 normal = a_pos_normal - 2.0 * pos; | |
| normal.y = normal.y * 2.0 - 1.0; | |
| v_normal = normal; | |
| // these transformations used to be applied in the JS and native code bases. | |
| // moved them into the shader for clarity and simplicity. | |
| gapwidth = gapwidth / 2.0; | |
| float halfwidth = width / 2.0; | |
| offset = -1.0 * offset; | |
| float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0); | |
| float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + (halfwidth == 0.0 ? 0.0 : ANTIALIASING); | |
| // Scale the extrusion vector down to a normal and then up by the line width | |
| // of this vertex. | |
| mediump vec2 dist = outset * a_extrude * scale; | |
| // Calculate the offset when drawing a line that is to the side of the actual line. | |
| // We do this by creating a vector that points towards the extrude, but rotate | |
| // it when we're drawing round end points (a_direction = -1 or 1) since their | |
| // extrude vector points in another direction. | |
| mediump float u = 0.5 * a_direction; | |
| mediump float t = 1.0 - abs(u); | |
| mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t); | |
| vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); | |
| gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; | |
| // calculate how much the perspective view squishes or stretches the extrude | |
| float extrude_length_without_perspective = length(dist); | |
| float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels); | |
| v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; | |
| v_width2 = vec2(outset, inset); | |
| } | |