

////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
	mode:
		0: 拉伸
		1: 居中
		2: 居中 + 背景模糊
*/
const int mode = 2;

float inBounds(vec2 p, vec4 rect) {
//   return all(lessThanEqual(rect.xy, p)) && all(lessThanEqual(p, rect.xy + rect.zw));

	vec2 pt = iResolution.xy * p;
	vec2 lt_out = floor(iResolution.xy * rect.xy) - vec2(1.0);
	vec2 rb_out = ceil(iResolution.xy * (rect.xy + rect.zw)) + vec2(1.0);

	if (all(lessThanEqual(lt_out, pt)) && all(lessThanEqual(pt, rb_out))) {
		vec2 lt_in = lt_out + vec2(1.0);
		vec2 rb_in = rb_out - vec2(1.0);
		
		if (all(lessThanEqual(lt_in, pt)) && all(lessThanEqual(pt, rb_in))) {
			return 1.0;
		} else {
			vec2 center = (lt_in + rb_in) / 2.0;
			float dx = 0.0;
			float dy = 0.0;

			if (pt.x <= center.x) {
				if (pt.y <= center.y) {
					dx = clamp(lt_in.x - pt.x, 0.0, 1.0);
					dy = clamp(lt_in.y - pt.y, 0.0, 1.0);
				} else {
					dx = clamp(lt_in.x - pt.x, 0.0, 1.0);
					dy = clamp(pt.y - rb_in.y, 0.0, 1.0);
				}
			} else {
				if (pt.y <= center.y) {
					dx = clamp(pt.x - rb_in.x, 0.0, 1.0);
					dy = clamp(lt_in.y - pt.y, 0.0, 1.0);
				} else {
					dx = clamp(pt.x - rb_in.x, 0.0, 1.0);
					dy = clamp(pt.y - rb_in.y, 0.0, 1.0);
				}
			}
			
			return (1.0 - dx) * (1.0 - dy);
		}
	} else {
		return 0.0;
	}
}

float inBounds(vec2 p) {
	return inBounds(p, vec4(0.0, 0.0, 1.0, 1.0));
}

const int iter = 8;
const float radius = 0.15;

void srand(vec2 a, out float r)
{
	r=sin(dot(a,vec2(1233.224,1743.335)));
}

float rand(inout float r)
{
	r=fract(3712.65*r+0.61432);
	return (r-0.5)*2.0;
}

vec4 FrostedGlass(vec2 uv)
{
	vec4 col = vec4(0.0);
	vec2 circle = vec2(radius) * vec2((iResolution.y / iResolution.x), 1.0);

	float r;
	srand(uv, r);

	for(int i=0; i<iter; i++)
	{
		col += texture2D(iChannel[0], uv + circle * vec2(rand(r), rand(r))) / float(iter);
	}

	return col;
}

vec4 background(vec2 uv)
{
	if (mode == 2) {
		return FrostedGlass(uv);
	}

	return vec4(0.0, 0.0, 0.0, 1.0);
}

void arrange(inout vec4 rect, vec2 sizeInner, vec2 sizeOutter)
{
	if (mode == 0) {
		rect = vec4(0.0, 0.0, 1.0, 1.0);
	} else {
		float aspectInner = sizeInner.x / sizeInner.y;

		if (iAspect > aspectInner) {
			rect.z = aspectInner / iAspect;
			rect.w = 1.0;
		} else {
			rect.z = 1.0;
			rect.w = iAspect / aspectInner;
		}
		rect.x = 0.5 - rect.z * 0.5;
		rect.y = 0.5 - rect.w * 0.5;
	}
}

float smooth_pulse(float e0, float e1, float e2, float e3, float t) {
    return clamp((smoothstep(e0, e1, t) - smoothstep(e2, e3, t)), 0.0, 1.0);
}

void motion(inout vec4 rect)
{
  float dur = 1.0;
  float step = smooth_pulse(0.0, dur, iDuration - dur, iDuration, iTime);

	rect.zw *= 1.0 - 0.5 * step;
	rect.x = 0.5 - rect.z * 0.5;
	rect.y = 0.5 - rect.w * 0.5;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	vec2 uv = fragCoord.xy / iResolution.xy;
	vec4 col = vec4(0.0);

	vec4 rect;
	arrange(rect, iChannelResolution[0].xy, iResolution.xy);
	motion(rect);

	col = texture2D(iChannel[0], (uv - rect.xy) / rect.zw);
	float mixStep = inBounds(uv, rect);
	if (mixStep < 1.0) {
		col = mix(background(uv), col, mixStep);
	}

	fragColor = col;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////

void main() {
    mainImage(gl_FragColor, gl_FragCoord.xy);
}
