<languageVersion : 1.0;>

kernel NewFilter
<   namespace : "Vortex";
    vendor : "Mr.doob";
    version : 1;
    description : "Vortex effect";
>
//@ parameter(s)
{
    input image4 src;
    output pixel4 dst;
    
    parameter float2 imgSize
    <
        defaultValue : float2(512.0, 512.0);
        minValue : float2(0.0,0.0);
        maxValue : float2(512.0,512.0);
    >;
    
    parameter float2 center
    <
        defaultValue : float2(256.0, 256.0);
        minValue : float2(0.0,0.0);
        maxValue : float2(512.0,512.0);        
    >;
    
    parameter float2 offset;
//@ evaluate(s)

    void evaluatePixel()
    {        
        float2 pos = (outCoord() - center) / imgSize;

        float pi = 3.141592653589793;
        float a = atan(pos.y,pos.x);
        float r = sqrt(pow(pos.x,2.0)+pow(pos.y,2.0));
        
        float u = 0.0;
        float v = 0.0;
        float w = 0.0;
        
        u += offset.x;
        v += offset.y;

//@ magic(s)
        
        // This is where the magic happens
        
        u += .5*a/pi + .1*r;
        v += pow(r,.1);
        w += 1.0;

        // End of the magic

//@ etcetera(s)

        u *= imgSize.x;
        v *= imgSize.y;
        
        if (u < 0.0) u += imgSize.x * ceil(-u / imgSize.x);
        if (v < 0.0) v += imgSize.y * ceil(-v / imgSize.y);
        if (u > imgSize.x) u -= imgSize.x * floor(u / imgSize.x);
        if (v > imgSize.y) v -= imgSize.y * floor(v / imgSize.y);
        
        dst = sampleNearest(src,float2(u, v));
        dst.rgb *= w;
    }
}