ruffle/render/wgpu/shaders/gradient.frag

87 lines
1.9 KiB
GLSL
Raw Normal View History

#version 450
layout(set = 1, binding = 2) uniform Colors {
vec4 mult_color;
vec4 add_color;
};
layout(std430, set = 1, binding = 3) buffer Gradient {
2020-05-20 22:02:42 +00:00
vec4 u_colors[16];
float u_ratios[16];
int u_gradient_type;
uint u_num_colors;
int u_repeat_mode;
2020-05-20 22:02:42 +00:00
int u_interpolation;
float u_focal_point;
};
layout(location=0) in vec2 frag_uv;
layout(location=0) out vec4 out_color;
2020-05-20 22:02:42 +00:00
vec3 linear_to_srgb(vec3 linear)
{
vec3 a = 12.92 * linear;
vec3 b = 1.055 * pow(linear, vec3(1.0 / 2.4)) - 0.055;
vec3 c = step(vec3(0.0031308), linear);
return mix(a, b, c);
}
void main() {
vec4 color;
int last = int(int(u_num_colors) - 1);
float t;
if( u_gradient_type == 0 )
{
t = frag_uv.x;
}
else if( u_gradient_type == 1 )
{
t = length(frag_uv * 2.0 - 1.0);
}
else if( u_gradient_type == 2 )
{
vec2 uv = frag_uv * 2.0 - 1.0;
vec2 d = vec2(u_focal_point, 0.0) - uv;
float l = length(d);
d /= l;
t = l / (sqrt(1.0 - u_focal_point*u_focal_point*d.y*d.y) + u_focal_point*d.x);
}
if( u_repeat_mode == 0 )
{
// Clamp
t = clamp(t, 0.0, 1.0);
}
else if( u_repeat_mode == 1 )
{
// Repeat
t = fract(t);
}
else
{
// Mirror
if( t < 0.0 )
{
t = -t;
}
if( (int(t)&1) == 0 ) {
t = fract(t);
} else {
t = 1.0 - fract(t);
}
}
int i = 0;
int j = 1;
t = clamp(t, u_ratios[0].x, u_ratios[last].x);
while( t > u_ratios[j].x )
{
i = j;
j++;
}
float a = (t - u_ratios[i].x) / (u_ratios[j].x - u_ratios[i].x);
color = mix(u_colors[i], u_colors[j], a);
2020-05-20 22:02:42 +00:00
if( u_interpolation != 0 ) {
color = vec4(linear_to_srgb(vec3(color)), color.a);
}
out_color = mult_color * color + add_color;
}