#if USE_AAA_UNIFORM == 1
#else
#endif

layout(binding = 0) uniform sampler2D g_input_texture_0;

layout(location = 0) in vec2 uv;
layout(location = 1) in vec4 layer_color;
layout(location = 0) out vec4 fragColor;

// AAASeed float uniforms mapping
// [1] = center U, [2] = center V, [3] = angle (deg), [4] = half-length,
// [5] = strength, [6] = radius
CONST float u_center_u    = aaa_fu_float[1];
CONST float u_center_v    = aaa_fu_float[2];
CONST float u_angle       = radians(aaa_fu_float[3]);
CONST float u_half_length = aaa_fu_float[4];
CONST float u_strength    = aaa_fu_float[5];
CONST float u_radius      = aaa_fu_float[6];

// helper function: projection of a point on a segment
vec2 project_point_on_segment(vec2 p, vec2 a, vec2 b)
{
	vec2 ab = b - a;
	float ab_len2 = dot(ab, ab);
	if(ab_len2 <= 0.0) return a;
	float t = dot(p - a, ab) / ab_len2;
	t = clamp(t, 0.0, 1.0);
	return a + ab * t;
}

void main(void)
{
	vec2 center = vec2(u_center_u, u_center_v);
	vec2 dir = vec2(cos(u_angle), sin(u_angle));
	vec2 a = center - dir * u_half_length;
	vec2 b = center + dir * u_half_length;

	vec2 proj = project_point_on_segment(uv, a, b);
	vec2 perp = uv - proj;
	float dist = length(perp);
	vec2 perp_dir = (dist > 1e-6) ? (perp / dist) : vec2(0.0);

	float fall = exp(- (dist * dist) / (u_radius * u_radius + 1e-6));
	float factor = 1.0 + u_strength * fall;
	vec2 new_uv = proj + perp_dir * (dist * factor);

	vec4 col;

	col.r = texture(g_input_texture_0, uv - a).r;
	col.g = texture(g_input_texture_0, clamp(new_uv, vec2(0.0), vec2(1.0))).g;
	col.b = texture(g_input_texture_0, clamp(new_uv, vec2(0.0), vec2(1.0))).b;
	col.a = 1;
	fragColor = col * layer_color;
}
