{
  "name": "Popups",
  "type": "fixed-intro",
  "duration": 3.0,
  "passes": [
    {
      "name": "popups",
      "inputs": [
        "default"
      ],
      "glsl": "precision highp float;

varying vec2 textureCoordinate;
varying vec2 sourceTextureCoordinate;

// default uniforms for all filters
uniform float time_sec;
uniform float strength;
uniform vec2 outputSize; // size of the output fbo
uniform vec2 inputSize; // size of the original default input texture
uniform vec2 tex0Size; // size of tex0 for this pass

// default uniforms for transitions and video effects
uniform float progress; // normalized 0-1

// default uniforms for video effects
uniform float duration; // in seconds
uniform float clipDuration; // in seconds

const vec2 compRes = vec2(1080.0,1920.0);

uniform float startF0;
uniform float endF0;
const vec2 centerPx0 = vec2(540.0,960.0);

uniform float startF1;
uniform float endF1;
uniform float maskScale1;
uniform float imgScale1;
const vec2 centerPx1 = vec2(550.0,953.0);

uniform float startF2;
uniform float endF2;
uniform float maskScale2;
uniform float imgScale2;
const vec2 centerPx2 = vec2(510.0,1040.0);

uniform float startF3;
uniform float endF3;
uniform float maskScale3;
uniform float imgScale3;
const vec2 centerPx3 = vec2(470.0,1130.0);

uniform float startF4;
uniform float endF4;
uniform float maskScale4;
uniform float imgScale4;
const vec2 centerPx4 = vec2(353.0,776.0);

uniform float startF5;
uniform float endF5;
uniform float maskScale5;
uniform float imgScale5;
const vec2 centerPx5 = vec2(522.0,648.0);

uniform float startF6;
uniform float endF6;
uniform float maskScale6;
uniform float imgScale6;
const vec2 centerPx6 = vec2(380.0,1230.0);

uniform float startF7;
uniform float endF7;
uniform float maskScale7;
uniform float imgScale7;
const vec2 centerPx7 = vec2(775.0,1150.0);

float fadeWindow(float f, float startF, float endF){
  float inF = smoothstep(startF, startF + 1.0, f);
  float outF = smoothstep(endF - 1.0, endF, f);
  return inF * (1.0 - outF);
}

float squareMask(vec2 uv, vec2 centerUV, float halfSizeUV, vec2 ratio){

  vec2 d = uv - centerUV;
  float r = max(abs(d.x) * ratio.x, abs(d.y));
  return step(r, halfSizeUV);
}

vec4 prepLayer(vec2 centerPx, float mScale){
  vec2 ctrUV = (centerPx - compRes * 0.5) * (outputSize / compRes) + outputSize * 0.5;
  float halfUV = (mScale * 0.5) * (min(outputSize.x, outputSize.y) / outputSize.y);
  return vec4((ctrUV / outputSize), halfUV, 0.0);
}

vec3 doLayer(vec4 prep, float imgScale,  float alpha, vec2 offset){
  if(alpha <= 0.0) return vec3(0.0);

  vec2 ratio = vec2(outputSize.x / outputSize.y, 1.0);
  float halfUV = prep.z;

  vec2 uv = (sourceTextureCoordinate - prep.xy) / imgScale + prep.xy;

  uv.y -= (halfUV / 2.0) + offset.y;
  uv.x -= offset.x;

  float mask = squareMask(sourceTextureCoordinate, prep.xy, halfUV, ratio);
  vec3 col = sampleInput(uv).rgb * alpha * mask;
  return col;
}

// effect uniforms
void main() {

  vec2 uv = sourceTextureCoordinate;
  vec2 ratio = vec2(outputSize.x / outputSize.y, 1.0);
  float frame = progress * 71.0;

  vec3 outCol = sampleInput(uv).rgb;

  vec4 p0 = prepLayer(centerPx0, 5.0);
  float a0 = fadeWindow(frame, startF0, endF0);
  outCol = mix(outCol, doLayer(p0, 1.5, 1.0, vec2(0.0,-p0.z / 2.0)), a0 );

  vec4 p1 = prepLayer(centerPx1, maskScale1);
  float a1 = fadeWindow(frame, startF1, endF1);
  float m1 = squareMask(uv, p1.xy, p1.z * imgScale1, ratio);
  outCol = mix(outCol, doLayer(p1, imgScale1, 1.0, vec2(0.0)), a1 * m1 );

  vec4 p2 = prepLayer(centerPx2, maskScale2);
  float a2 = fadeWindow(frame, startF2, endF2);
  float m2 = squareMask(uv, p2.xy, p2.z * imgScale2, ratio);
  outCol = mix(outCol, doLayer(p2, imgScale2, 1.0, vec2(0.0)), a2 * m2);

  vec4 p3 = prepLayer(centerPx3, maskScale3);
  float a3 = fadeWindow(frame, startF3, endF3);
  float m3 = squareMask(uv, p3.xy, p3.z * imgScale3, ratio);
  outCol = mix(outCol, doLayer(p3, imgScale3, 1.0, vec2(0.0)), a3 * m3);

  vec4 p4 = prepLayer(centerPx4, maskScale4);
  float a4 = fadeWindow(frame, startF4, endF4);
  float m4 = squareMask(uv, p4.xy, p4.z * imgScale4, ratio);
  outCol = mix(outCol, doLayer(p4, imgScale4, 1.0, vec2(-0.2, -0.25)), a4 * m4);

  vec4 p6 = prepLayer(centerPx6, maskScale6);
  float a6 = fadeWindow(frame, startF6, endF6);
  float m6 = squareMask(uv, p6.xy, p6.z * imgScale6, ratio);
  outCol = mix(outCol, doLayer(p6, imgScale6, 1.0, vec2(-0.2, 0.05)), a6 * m6);

  vec4 p7 = prepLayer(centerPx7, maskScale7);
  float a7 = fadeWindow(frame, startF7, endF7);
  float m7 = squareMask(uv, p7.xy, p7.z * imgScale7, ratio);
  outCol = mix(outCol, doLayer(p7, imgScale7, 1.0, vec2(0.1, 0.05)), a7 * m7);

  vec4 p5 = prepLayer(centerPx5, maskScale5);
  float a5 = fadeWindow(frame, startF5, endF5);
  float m5 = squareMask(uv, p5.xy, p5.z * imgScale5, ratio);
  outCol = mix(outCol, doLayer(p5, imgScale5, 1.0, vec2(-0.05, -0.3)), a5 * m5);

  vec4 color = vec4(outCol,1.0);
  gl_FragColor = toOutputFormat(color);
}
",
      "metal": "using namespace metal;
struct fragmentIn { float2 textureCoordinate [[user(locn0)]]; float2 sourceTextureCoordinate [[user(locn1)]]; };
struct fragmentOut { float4 _gl_FragColor [[color(0)]]; };
typedef struct {
  float4x4 content_transform;
  float4x4 texture_transform;
  float strength;
  float progress;
  float time_sec;
  float duration_sec;
  float clip_duration_sec;
  float2 input_size;
  float2 output_size;
  float2 tex0Size;
  float startF0;
  float endF0;
  float startF1;
  float endF1;
  float maskScale1;
  float imgScale1;
  float startF2;
  float endF2;
  float maskScale2;
  float imgScale2;
  float startF3;
  float endF3;
  float maskScale3;
  float imgScale3;
  float startF4;
  float endF4;
  float maskScale4;
  float imgScale4;
  float startF5;
  float endF5;
  float maskScale5;
  float imgScale5;
  float startF6;
  float endF6;
  float maskScale6;
  float imgScale6;
  float startF7;
  float endF7;
  float maskScale7;
  float imgScale7;
 } Uniforms;
constant float2 compRes = float2(1080.0,1920.0);

constant float2 centerPx0 = float2(540.0,960.0);

constant float2 centerPx1 = float2(550.0,953.0);

constant float2 centerPx2 = float2(510.0,1040.0);

constant float2 centerPx3 = float2(470.0,1130.0);

constant float2 centerPx4 = float2(353.0,776.0);

constant float2 centerPx5 = float2(522.0,648.0);

constant float2 centerPx6 = float2(380.0,1230.0);

constant float2 centerPx7 = float2(775.0,1150.0);

float fadeWindow(float f, float startF, float endF){
  float inF = smoothstep(startF, startF + 1.0, f);
  float outF = smoothstep(endF - 1.0, endF, f);
  return inF * (1.0 - outF);
}

float squareMask(float2 uv, float2 centerUV, float halfSizeUV, float2 ratio){

  float2 d = uv - centerUV;
  float r = max(abs(d.x) * ratio.x, abs(d.y));
  return step(r, halfSizeUV);
}

float4 prepLayer(float2 centerPx, float mScale, constant Uniforms & uniforms){
  float2 ctrUV = (centerPx - compRes * 0.5) * (uniforms.output_size / compRes) + uniforms.output_size * 0.5;
  float halfUV = (mScale * 0.5) * (min(uniforms.output_size.x, uniforms.output_size.y) / uniforms.output_size.y);
  return float4((ctrUV / uniforms.output_size), halfUV, 0.0);
}

float3 doLayer(float4 prep, float imgScale,  float alpha, float2 offset, DefaultInputs defaultInputs, constant Uniforms & uniforms, fragmentIn in){
  if(alpha <= 0.0) return float3(0.0);

  float2 ratio = float2(uniforms.output_size.x / uniforms.output_size.y, 1.0);
  float halfUV = prep.z;

  float2 uv = (in.sourceTextureCoordinate - prep.xy) / imgScale + prep.xy;

  uv.y -= (halfUV / 2.0) + offset.y;
  uv.x -= offset.x;

  float mask = squareMask(in.sourceTextureCoordinate, prep.xy, halfUV, ratio);
  float3 col = sampleInput(defaultInputs, uv).rgb * alpha * mask;
  return col;
}

// effect uniforms
fragment fragmentOut fragmentShader(fragmentIn in [[stage_in]],
 constant Uniforms & uniforms [[buffer(1)]],
 DefaultInputs defaultInputs) {

  float2 uv = in.sourceTextureCoordinate;
  float2 ratio = float2(uniforms.output_size.x / uniforms.output_size.y, 1.0);
  float frame = uniforms.progress * 71.0;

  float3 outCol = sampleInput(defaultInputs, uv).rgb;

  float4 p0 = prepLayer(centerPx0, 5.0, uniforms);
  float a0 = fadeWindow(frame, uniforms.startF0, uniforms.endF0);
  outCol = mix(outCol, doLayer(p0, 1.5, 1.0, float2(0.0,-p0.z / 2.0), defaultInputs, uniforms, in), a0 );

  float4 p1 = prepLayer(centerPx1, uniforms.maskScale1, uniforms);
  float a1 = fadeWindow(frame, uniforms.startF1, uniforms.endF1);
  float m1 = squareMask(uv, p1.xy, p1.z * uniforms.imgScale1, ratio);
  outCol = mix(outCol, doLayer(p1, uniforms.imgScale1, 1.0, float2(0.0), defaultInputs, uniforms, in), a1 * m1 );

  float4 p2 = prepLayer(centerPx2, uniforms.maskScale2, uniforms);
  float a2 = fadeWindow(frame, uniforms.startF2, uniforms.endF2);
  float m2 = squareMask(uv, p2.xy, p2.z * uniforms.imgScale2, ratio);
  outCol = mix(outCol, doLayer(p2, uniforms.imgScale2, 1.0, float2(0.0), defaultInputs, uniforms, in), a2 * m2);

  float4 p3 = prepLayer(centerPx3, uniforms.maskScale3, uniforms);
  float a3 = fadeWindow(frame, uniforms.startF3, uniforms.endF3);
  float m3 = squareMask(uv, p3.xy, p3.z * uniforms.imgScale3, ratio);
  outCol = mix(outCol, doLayer(p3, uniforms.imgScale3, 1.0, float2(0.0), defaultInputs, uniforms, in), a3 * m3);

  float4 p4 = prepLayer(centerPx4, uniforms.maskScale4, uniforms);
  float a4 = fadeWindow(frame, uniforms.startF4, uniforms.endF4);
  float m4 = squareMask(uv, p4.xy, p4.z * uniforms.imgScale4, ratio);
  outCol = mix(outCol, doLayer(p4, uniforms.imgScale4, 1.0, float2(-0.2, -0.25), defaultInputs, uniforms, in), a4 * m4);

  float4 p6 = prepLayer(centerPx6, uniforms.maskScale6, uniforms);
  float a6 = fadeWindow(frame, uniforms.startF6, uniforms.endF6);
  float m6 = squareMask(uv, p6.xy, p6.z * uniforms.imgScale6, ratio);
  outCol = mix(outCol, doLayer(p6, uniforms.imgScale6, 1.0, float2(-0.2, 0.05), defaultInputs, uniforms, in), a6 * m6);

  float4 p7 = prepLayer(centerPx7, uniforms.maskScale7, uniforms);
  float a7 = fadeWindow(frame, uniforms.startF7, uniforms.endF7);
  float m7 = squareMask(uv, p7.xy, p7.z * uniforms.imgScale7, ratio);
  outCol = mix(outCol, doLayer(p7, uniforms.imgScale7, 1.0, float2(0.1, 0.05), defaultInputs, uniforms, in), a7 * m7);

  float4 p5 = prepLayer(centerPx5, uniforms.maskScale5, uniforms);
  float a5 = fadeWindow(frame, uniforms.startF5, uniforms.endF5);
  float m5 = squareMask(uv, p5.xy, p5.z * uniforms.imgScale5, ratio);
  outCol = mix(outCol, doLayer(p5, uniforms.imgScale5, 1.0, float2(-0.05, -0.3), defaultInputs, uniforms, in), a5 * m5);

  float4 color = float4(outCol,1.0);
  return {toOutputFormat(color)};
}
",
      "uniforms": {
        "startF0": {
          "value": 4.0
        },
        "endF0": {
          "value": 72.0
        },
        "startF1": {
          "value": 9.0
        },
        "endF1": {
          "value": 29.0
        },
        "maskScale1": {
          "value": 0.84
        },
        "imgScale1": {
          "value": 0.84
        },
        "startF2": {
          "value": 12.0
        },
        "endF2": {
          "value": 32.0
        },
        "maskScale2": {
          "value": 0.84
        },
        "imgScale2": {
          "value": 0.84
        },
        "startF3": {
          "value": 14.0
        },
        "endF3": {
          "value": 34.0
        },
        "maskScale3": {
          "value": 0.84
        },
        "imgScale3": {
          "value": 0.84
        },
        "startF4": {
          "value": 23.0
        },
        "endF4": {
          "value": 35.0
        },
        "maskScale4": {
          "value": 0.77
        },
        "imgScale4": {
          "value": 1.0
        },
        "startF5": {
          "value": 34.0
        },
        "endF5": {
          "value": 72.0
        },
        "maskScale5": {
          "value": 0.87
        },
        "imgScale5": {
          "value": 1.0
        },
        "startF6": {
          "value": 39.0
        },
        "endF6": {
          "value": 72.0
        },
        "maskScale6": {
          "value": 0.7
        },
        "imgScale6": {
          "value": 0.6
        },
        "startF7": {
          "value": 41.0
        },
        "endF7": {
          "value": 72.0
        },
        "maskScale7": {
          "value": 0.62
        },
        "imgScale7": {
          "value": 0.725
        }
      }
    }
  ]
}
