summaryrefslogtreecommitdiffstats
path: root/glow/src/shader/common/gradient.frag
blob: 1afb557d679d285c70ae2afbd37a3428b66d12fb (plain) (blame)
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
// GLSL does not support dynamically sized arrays without SSBOs
#define MAX_STOPS 64

#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif

#ifdef HIGHER_THAN_300
layout (location = 0) out vec4 fragColor;
#define gl_FragColor fragColor
#endif

in vec2 raw_position;

uniform vec2 gradient_start;
uniform vec2 gradient_end;

uniform uint color_stops_size;
uniform float color_stop_offsets[MAX_STOPS];
uniform vec4 color_stop_colors[MAX_STOPS];

//TODO: rewrite without branching to make ALUs happy
void main() {
    vec2 gradient_vec = vec2(gradient_end - gradient_start);
    vec2 current_vec = vec2(raw_position.xy - gradient_start);
    vec2 unit = normalize(gradient_vec);
    float coord_offset = dot(unit, current_vec) / length(gradient_vec);

    for (uint i = 0; i < color_stops_size - 1; i++) {
        float stop_offset = color_stop_offsets[i];
        float next_stop_offset = color_stop_offsets[i + 1];

        if (stop_offset <= coord_offset && coord_offset <= next_stop_offset) {
            fragColor = mix(color_stop_colors[i], color_stop_colors[i+1], smoothstep(
                stop_offset,
                next_stop_offset,
                coord_offset
            ));
        } else if (coord_offset < color_stop_offsets[0]) {
            fragColor = color_stop_colors[0];
        } else if (coord_offset > color_stop_offsets[color_stops_size - 1]) {
            fragColor = color_stop_colors[color_stops_size - 1];
        }
    }
}