gtk2/gsk/resources/glsl/radial_gradient.glsl
Alexander Larsson bacb3affb3 gl: Add some namespacing to the preamble symbols
This adds a gsk prefix to the stuff in the preamble, as we want to
avoid it conflicting with things in the main shader. Especially once
we start allow some customization of shaders.
2020-09-29 09:51:16 +02:00

85 lines
2.2 KiB
GLSL

// VERTEX_SHADER
uniform float u_start;
uniform float u_end;
uniform float u_color_stops[6 * 5];
uniform int u_num_color_stops;
uniform vec2 u_radius;
uniform vec2 u_center;
_OUT_ vec2 center;
_OUT_ vec4 color_stops[8];
_OUT_ float color_offsets[8];
_OUT_ float start;
_OUT_ float end;
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
center = (u_modelview * vec4(u_center, 0, 1)).xy;
start = u_start;
end = u_end;
for (int i = 0; i < u_num_color_stops; i ++) {
color_offsets[i] = u_color_stops[(i * 5) + 0];
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]));
}
}
// FRAGMENT_SHADER:
#ifdef GSK_LEGACY
uniform int u_num_color_stops;
#else
uniform highp int u_num_color_stops;
#endif
uniform vec2 u_radius;
uniform float u_end;
_IN_ vec2 center;
_IN_ vec4 color_stops[8];
_IN_ float color_offsets[8];
_IN_ float start;
_IN_ float end;
// The offsets in the color stops are relative to the
// start and end values of the gradient.
float abs_offset(float offset) {
return start + ((end - start) * offset);
}
void main() {
vec2 pixel = gsk_get_frag_coord();
vec2 rel = (center - pixel) / (u_radius);
float d = sqrt(dot(rel, rel));
if (d < abs_offset (color_offsets[0])) {
gskSetOutputColor(color_stops[0] * u_alpha);
return;
}
if (d > end) {
gskSetOutputColor(color_stops[u_num_color_stops - 1] * u_alpha);
return;
}
vec4 color = vec4(0, 0, 0, 0);
for (int i = 1; i < u_num_color_stops; i++) {
float last_offset = abs_offset(color_offsets[i - 1]);
float this_offset = abs_offset(color_offsets[i]);
// We have color_stops[i - 1] at last_offset and color_stops[i] at this_offset.
// We now need to map `d` between those two offsets and simply mix linearly between them
if (d >= last_offset && d <= this_offset) {
float f = (d - last_offset) / (this_offset - last_offset);
color = mix(color_stops[i - 1], color_stops[i], f);
break;
}
}
gskSetOutputColor(color * u_alpha);
}