// Default Velocity Collection Fragment Shader
#version 100

precision highp float;

uniform sampler2D Texture;
uniform sampler2D VelocityTexture;
uniform vec2 RandomXY;
#if !SINGLE_OBJECT
uniform sampler2D ObjectTexture;
uniform vec2 VelocityTextureSize;
#endif
uniform vec2 VelocityScale;

varying vec2 v_TexCoord;
varying vec2 v_VelocityTexCoord;

const float Pi = 3.1415926;
const float TwoPi = 6.2831852;

const float sineConstB = 1.2732396; /* = 4./Pi; */
const float sineConstC = -0.40528476; /* = -4./(Pi*Pi); */

float fastSine(float angle)
{
    float theAngle = mod(angle + Pi, TwoPi) - Pi;
    return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);
}

float randomAmount(vec2 seed) {
#define USE_RANDOM 1
#if USE_RANDOM
    return fract(fastSine(dot(mix(RandomXY, seed.xy, 0.8), vec2(12.9898,78.233))) * 43758.5453);
#else
    return 1.0;
#endif
}

float randomAmountAround1(vec2 seed) {
    return 0.85 + 0.3 * randomAmount(seed);
}

vec4 colorFromTextureCoordinate(vec2 coordinate, vec2 originalVelocity, vec4 originalColor) {
    vec4 result = texture2D(Texture, coordinate);
    return result;
}


void main()
{
    vec4 originalColor = texture2D(Texture, v_TexCoord.xy);
    
    vec2 tileVelocityTexCoord = v_VelocityTexCoord;
#if !SINGLE_OBJECT
    vec2 tileVelocityTexCoordRandomness = vec2(randomAmount(v_VelocityTexCoord), randomAmount(vec2(v_VelocityTexCoord.y, v_VelocityTexCoord.x)));
    tileVelocityTexCoord += (vec2(0.5) - tileVelocityTexCoordRandomness) /  VelocityTextureSize;
    tileVelocityTexCoord = clamp(tileVelocityTexCoord, vec2(0), vec2(1));
#endif
    vec3 tileVelocity = texture2D(VelocityTexture, tileVelocityTexCoord).xyz;
    
    vec4 color = originalColor;
    
    vec2 velocityTest = tileVelocity.xy - vec2(0.5);
    if (tileVelocity.z >= 0.05 && dot(velocityTest,velocityTest) > 1e-5) {
        /* Only sample if we have an actual velocity! */
        
        /* Remap from [0,1] to [-1,1] */
        tileVelocity.xy = tileVelocity.xy*2.0 - vec2(1);
        tileVelocity.xy *= VelocityScale;
        
        /* Remap from pixel to texture coords and apply VelocityScale */
        vec2 perpTileVelocity = vec2(tileVelocity.y, -tileVelocity.x);
        
#if !SINGLE_OBJECT
        vec3 pixelVelocity3Value = texture2D(ObjectTexture, v_TexCoord).xyz;
        vec2 pixelVelocity = pixelVelocity3Value.z==0.0 ? vec2(0) : (pixelVelocity3Value.xy * 2.0 - vec2(1)) * VelocityScale;
        vec2 centerDirectionVelocity = mix(pixelVelocity.xy,perpTileVelocity,clamp((length(pixelVelocity)-0.5)*0.66667,0.0,1.0));
#else
        vec3 pixelVelocity3Value = vec3(0);
        vec2 centerDirectionVelocity = tileVelocity.xy;
#endif
        
        float sampleCountAdjust = 1.0/(float(SAMPLE_COUNT)+1.0);
        
        bool usePerpendicularVelocity = false;
        for (int s=0; s<SAMPLE_COUNT; s++) {
            float lerpValue = -1.0 + 2.0 * (float(s) * sampleCountAdjust);
            
            vec2 velocityDirection = usePerpendicularVelocity ? tileVelocity.xy : centerDirectionVelocity;
            usePerpendicularVelocity = pixelVelocity3Value.z==0.0 ? true : !usePerpendicularVelocity;
            
            float randAmt = 1.0;
#if !SINGLE_OBJECT
            randAmt = randomAmountAround1(vec2(velocityDirection.x, velocityDirection.y + float(s)) + v_TexCoord.xy + originalColor.yx);
#endif
            vec2 coord = velocityDirection * vec2(lerpValue) * randAmt + v_TexCoord.xy;
            color += texture2D(Texture, coord);
        }
        
        color *= sampleCountAdjust;
        
#define DEBUG_DRAW_RED_IF_TOO_MUCH_VELOCITY 0
#if DEBUG_DRAW_RED_IF_TOO_MUCH_VELOCITY
        if (abs(tileVelocity.x) == 1.0 || abs(tileVelocity.y) == 1.0) {
            color = vec4(1,0,0,1);
        }
#endif
    }
    
    gl_FragColor = color;
    
}
