2019-12-17 11:20:18 +00:00
|
|
|
// VERTEX_SHADER
|
|
|
|
uniform vec2 u_start_point;
|
|
|
|
uniform vec2 u_end_point;
|
2020-09-21 19:23:57 +00:00
|
|
|
uniform float u_color_stops[6 * 5];
|
2019-12-17 17:11:45 +00:00
|
|
|
uniform int u_num_color_stops;
|
2019-12-17 11:20:18 +00:00
|
|
|
|
|
|
|
_OUT_ vec2 startPoint;
|
|
|
|
_OUT_ vec2 endPoint;
|
|
|
|
_OUT_ float maxDist;
|
|
|
|
_OUT_ vec2 gradient;
|
|
|
|
_OUT_ float gradientLength;
|
2020-09-26 06:43:36 +00:00
|
|
|
_OUT_ vec4 color_stops[6];
|
|
|
|
_OUT_ float color_offsets[6];
|
2019-12-17 11:20:18 +00:00
|
|
|
|
2019-12-14 21:06:12 +00:00
|
|
|
void main() {
|
|
|
|
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
|
|
|
|
2019-12-17 11:20:18 +00:00
|
|
|
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);
|
2019-12-17 17:11:45 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < u_num_color_stops; i ++) {
|
|
|
|
color_offsets[i] = u_color_stops[(i * 5) + 0];
|
2020-09-18 09:35:29 +00:00
|
|
|
color_stops[i] = gsk_premultiply(vec4(u_color_stops[(i * 5) + 1],
|
|
|
|
u_color_stops[(i * 5) + 2],
|
|
|
|
u_color_stops[(i * 5) + 3],
|
|
|
|
u_color_stops[(i * 5) + 4]));
|
2019-12-17 17:11:45 +00:00
|
|
|
}
|
2019-12-14 21:06:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FRAGMENT_SHADER:
|
2019-12-17 17:11:45 +00:00
|
|
|
#ifdef GSK_LEGACY
|
2017-11-30 17:47:55 +00:00
|
|
|
uniform int u_num_color_stops;
|
2019-12-17 17:11:45 +00:00
|
|
|
#else
|
|
|
|
uniform highp int u_num_color_stops; // Why? Because it works like this.
|
|
|
|
#endif
|
2019-12-17 11:20:18 +00:00
|
|
|
|
|
|
|
_IN_ vec2 startPoint;
|
|
|
|
_IN_ vec2 endPoint;
|
|
|
|
_IN_ float maxDist;
|
|
|
|
_IN_ vec2 gradient;
|
|
|
|
_IN_ float gradientLength;
|
2020-09-26 06:43:36 +00:00
|
|
|
_IN_ vec4 color_stops[6];
|
|
|
|
_IN_ float color_offsets[6];
|
2019-12-17 17:11:45 +00:00
|
|
|
|
2017-11-03 12:09:02 +00:00
|
|
|
void main() {
|
|
|
|
// Position relative to startPoint
|
2020-09-18 09:35:29 +00:00
|
|
|
vec2 pos = gsk_get_frag_coord() - startPoint;
|
2017-11-03 12:09:02 +00:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
2019-12-17 17:11:45 +00:00
|
|
|
vec4 color = color_stops[0];
|
2017-11-30 17:47:55 +00:00
|
|
|
for (int i = 1; i < u_num_color_stops; i ++) {
|
2019-12-17 17:11:45 +00:00
|
|
|
if (offset >= color_offsets[i - 1]) {
|
|
|
|
float o = (offset - color_offsets[i - 1]) / (color_offsets[i] - color_offsets[i - 1]);
|
|
|
|
color = mix(color_stops[i - 1], color_stops[i], clamp(o, 0.0, 1.0));
|
2017-11-03 12:09:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-18 09:35:29 +00:00
|
|
|
gskSetOutputColor(color * u_alpha);
|
2017-11-03 12:09:02 +00:00
|
|
|
}
|