uniform sampler2D colorTexture;
uniform sampler2D fireTexture;

uniform vec2 viewSize;
uniform float time;

const float speed = 2.0;
const float distortionFactor = 0.04;

void main()
{
    vec2 texcoord = gl_FragCoord.xy / viewSize;

    vec2 uv = gl_TexCoord[0].st;
    float timeScaled = time * speed;

    // Generate noisy x value
    vec2 n0Uv = vec2(uv.x*1.4 + 0.01, uv.y - timeScaled*0.69);
    vec2 n1Uv = vec2(uv.x*0.5 - 0.033, uv.y*2.0 - timeScaled*0.12);
    vec2 n2Uv = vec2(uv.x*0.94 + 0.02, uv.y*3.0 - timeScaled*0.61);
    float n0 = (texture2D(fireTexture, n0Uv).w-0.5)*2.0;
    float n1 = (texture2D(fireTexture, n1Uv).w-0.5)*2.0;
    float n2 = (texture2D(fireTexture, n2Uv).w-0.5)*2.0;
    float noiseA = clamp(n0 + n1 + n2, -1.0, 1.0);

    // Generate noisy y value
    vec2 n0UvB = vec2(uv.x*0.7 - 0.01, uv.y - timeScaled*0.27);
    vec2 n1UvB = vec2(uv.x*0.45 + 0.033, uv.y*1.9 - timeScaled*0.61);
    vec2 n2UvB = vec2(uv.x*0.8 - 0.02, uv.y*2.5 - timeScaled*0.51);
    float n0B = (texture2D(fireTexture, n0UvB).w-0.5)* 2.0;
    float n1B = (texture2D(fireTexture, n1UvB).w-0.5)*2.0;
    float n2B = (texture2D(fireTexture, n2UvB).w-0.5)*2.0;
    float noiseB = clamp(n0B + n1B + n2B, -1.0, 1.0);

    vec2 finalNoise = vec2(noiseA, noiseB);
    float perturb = (1.0 - uv.y) * 0.35 + 0.02;
    finalNoise = (finalNoise * perturb) + uv - 0.02;

    vec4 fireColor = texture2D(fireTexture, finalNoise);
    fireColor = vec4(fireColor.x*2.0, fireColor.y*0.9, (fireColor.y/fireColor.x)*0.2, 1.0);
    finalNoise = clamp(finalNoise, 0.05, 1.0);
    fireColor.w = texture2D(fireTexture, finalNoise).z*2.0;
    fireColor.w = fireColor.w*texture2D(fireTexture, uv).z;
    
    // Heat haze effect
    vec2 distortionMapCoordinate = uv;
    distortionMapCoordinate.t -= timeScaled;
    vec4 distortionMapValue = texture2D(fireTexture, distortionMapCoordinate);
    vec2 distortionPositionOffset = (distortionMapValue.xy) * distortionFactor;
    distortionPositionOffset *= (1.0 - uv.t);
    vec2 distortedTextureCoordinate = texcoord - distortionPositionOffset;

    float mask = texture2D(fireTexture, uv).b;
    vec2 tc = distortedTextureCoordinate * mask + texcoord * (1.0 - mask);
    vec4 backColor = texture2D(colorTexture, tc);
    
    gl_FragColor = backColor + fireColor * fireColor.a;
    gl_FragColor.a = 1.0;
}

