// john-chapman-graphics.blogspot.co.uk/2013/02/pseudo-lens-flare.html
@export clay.compositor.lensflare

#define SAMPLE_NUMBER 8

uniform sampler2D texture;
uniform sampler2D lenscolor;

uniform vec2 textureSize : [512, 512];

uniform float dispersal : 0.3;
uniform float haloWidth : 0.4;
uniform float distortion : 1.0;

varying vec2 v_Texcoord;

@import clay.util.rgbm

vec4 textureDistorted(
    in vec2 texcoord,
    in vec2 direction,
    in vec3 distortion
) {
    return vec4(
        decodeHDR(texture2D(texture, texcoord + direction * distortion.r)).r,
        decodeHDR(texture2D(texture, texcoord + direction * distortion.g)).g,
        decodeHDR(texture2D(texture, texcoord + direction * distortion.b)).b,
        1.0
    );
}

void main()
{
    vec2 texcoord = -v_Texcoord + vec2(1.0); // Flip texcoords
    vec2 textureOffset = 1.0 / textureSize;

    vec2 ghostVec = (vec2(0.5) - texcoord) * dispersal;
    vec2 haloVec = normalize(ghostVec) * haloWidth;

    vec3 distortion = vec3(-textureOffset.x * distortion, 0.0, textureOffset.x * distortion);
    //Sample ghost
    vec4 result = vec4(0.0);
    for (int i = 0; i < SAMPLE_NUMBER; i++)
    {
        vec2 offset = fract(texcoord + ghostVec * float(i));

        float weight = length(vec2(0.5) - offset) / length(vec2(0.5));
        weight = pow(1.0 - weight, 10.0);

        result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;
    }

    result *= texture2D(lenscolor, vec2(length(vec2(0.5) - texcoord)) / length(vec2(0.5)));
    //Sample halo
    float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));
    weight = pow(1.0 - weight, 10.0);
    vec2 offset = fract(texcoord + haloVec);
    result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;

    gl_FragColor = result;
}
@end