precision highp float;
#define iChannel0 inputImageTexture
#define texture(a,b) texture2D(a,fract(b))
#define fragColor gl_FragColor
varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

uniform highp float iTime;

uniform highp vec2 iResolution;

const float pi = 3.14159265358979323846;
const float epsilon = 1e-6;

const float fringeExp = 2.3;
const float fringeScale = 0.02;
const float distortionExp = 2.0;
const float distortionScale = 0.65;

const float startAngle = 1.23456 + pi;    // tweak to get different fringe colouration
const float angleStep = pi * 2.0 / 3.0;    // space samples every 120 degrees

void main() {
    highp vec2 baseUV = textureCoordinate;
    highp vec2 fromCentre = baseUV - vec2(0.5, 0.5);
    // correct for aspect ratio
    fromCentre.y *= iResolution.y / iResolution.x;
    float radius = length(fromCentre);
    fromCentre = radius > epsilon
    ? (fromCentre * (1.0 / radius))
    : vec2(0);

    float strength = 1.5;// - (iMouse.x / iResolution.x);
    float rotation = sin(iTime) * 2.0 * pi;

    float fringing = fringeScale * pow(radius, fringeExp) * strength;
    float distortion = distortionScale * pow(radius, distortionExp) * strength;

    highp vec2 distortUV = baseUV - fromCentre * distortion;

    float angle;
    highp vec2 dir;

    angle = startAngle + rotation;
    dir = vec2(sin(angle), cos(angle));
    highp vec4 redPlane = texture(iChannel0,    distortUV + fringing * dir);
    angle += angleStep;
    dir = vec2(sin(angle), cos(angle));
    highp vec4 greenPlane = texture(iChannel0,    distortUV + fringing * dir);
    angle += angleStep;
    dir = vec2(sin(angle), cos(angle));
    highp vec4 bluePlane = texture(iChannel0,    distortUV + fringing * dir);

    fragColor = vec4(redPlane.r, greenPlane.g, bluePlane.b, 1.0);
}