summaryrefslogtreecommitdiff
path: root/gsk/ngl/resources/radial_gradient.glsl
blob: 0ab3fdf07ab48aceda621dd6c25b04057b16d89a (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
65
66
67
68
69
70
71
72
73
74
// VERTEX_SHADER
uniform vec4 u_geometry;

_NOPERSPECTIVE_ _OUT_ vec2 coord;

void main() {
  gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));

  vec2 mv0 = u_modelview[0].xy;
  vec2 mv1 = u_modelview[1].xy;
  vec2 offset = aPosition - u_geometry.xy;
  vec2 dir = vec2(dot(mv0, offset),
                  dot(mv1, offset));

  coord = dir * u_geometry.zw;
}

// FRAGMENT_SHADER:
#ifdef GSK_LEGACY
uniform int u_num_color_stops;
#else
uniform highp int u_num_color_stops;
#endif

uniform bool u_repeat;
uniform vec2 u_range;
uniform float u_color_stops[6 * 5];

_NOPERSPECTIVE_ _IN_ vec2 coord;

float get_offset(int index) {
  return u_color_stops[5 * index];
}

vec4 get_color(int index) {
  int base = 5 * index + 1;

  return vec4(u_color_stops[base],
              u_color_stops[base + 1],
              u_color_stops[base + 2],
              u_color_stops[base + 3]);
}

void main() {
  // Reverse scale
  float offset = length(coord) * u_range.x + u_range.y;

  if (u_repeat) {
    offset = fract(offset);
  }

  if (offset < get_offset(0)) {
    gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
    return;
  }

  int n = u_num_color_stops - 1;
  for (int i = 0; i < n; i++) {
    float curr_offset = get_offset(i);
    float next_offset = get_offset(i + 1);

    if (offset >= curr_offset && offset < next_offset) {
      float f = (offset - curr_offset) / (next_offset - curr_offset);
      vec4 curr_color = gsk_premultiply(get_color(i));
      vec4 next_color = gsk_premultiply(get_color(i + 1));
      vec4 color = mix(curr_color, next_color, f);

      gskSetOutputColor(color * u_alpha);
      return;
    }
  }

  gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
}