blob: 0b5fefce834e68cf7b7fb8b4691dce17751f2bbb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
// VERTEX_SHADER
uniform vec2 u_start_point;
uniform vec2 u_end_point;
_OUT_ vec2 startPoint;
_OUT_ vec2 endPoint;
_OUT_ float maxDist;
_OUT_ vec2 gradient;
_OUT_ float gradientLength;
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
startPoint = (u_modelview * vec4(u_start_point, 0, 1)).xy;
endPoint = (u_modelview * vec4(u_end_point, 0, 1)).xy;
maxDist = length(endPoint - startPoint);
// Gradient direction
gradient = endPoint - startPoint;
gradientLength = length(gradient);
}
// FRAGMENT_SHADER:
uniform vec4 u_color_stops[8];
uniform float u_color_offsets[8];
uniform int u_num_color_stops;
_IN_ vec2 startPoint;
_IN_ vec2 endPoint;
_IN_ float maxDist;
_IN_ vec2 gradient;
_IN_ float gradientLength;
vec4 fragCoord() {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
return f;
}
void main() {
// Position relative to startPoint
vec2 pos = fragCoord().xy - startPoint;
// Current pixel, projected onto the line between the start point and the end point
// The projection will be relative to the start point!
vec2 proj = (dot(gradient, pos) / (gradientLength * gradientLength)) * gradient;
// Offset of the current pixel
float offset = length(proj) / maxDist;
vec4 color = u_color_stops[0];
for (int i = 1; i < u_num_color_stops; i ++) {
if (offset >= u_color_offsets[i - 1]) {
float o = (offset - u_color_offsets[i - 1]) / (u_color_offsets[i] - u_color_offsets[i - 1]);
color = mix(u_color_stops[i - 1], u_color_stops[i], clamp(o, 0.0, 1.0));
}
}
/* Pre-multiply */
color.rgb *= color.a;
setOutputColor(color * u_alpha);
}
|