#version 120
#define iResolution gl_TexCoord[0]
#define iTime gl_TexCoord[0].z
#define offset floor((iTime+4.0)*10.0)*2.2
#define pi acos(-1.)

float sdCircle( vec2 p, float r, float r2 )
{
    return abs(length(p) - r) -r2;
}

float sdSegment( vec2 p, vec2 a, vec2 b )
{
    vec2 pa = p-a, ba = b-a;
    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
    return length( pa - ba*h ) - 0.04;
}

float child(vec2 p) {
return min(min(min(min(min(
sdSegment(p,vec2(0.25,0.075),vec2(0.35,0.28)),
sdSegment(p,vec2(0.45,0.075),vec2(0.35,0.25))),
sdSegment(p,vec2(0.34,0.4),vec2(0.35,0.25))),
sdSegment(p,vec2(0.34,0.4),vec2(0.45,0.3))),
sdSegment(p,vec2(0.34,0.4),vec2(0.25,0.3))),
sdCircle(p-vec2(0.35,0.48),0.06,0.03));
}

float parent(vec2 p) {
return min(min(min(min(min(
sdSegment(p,vec2(0.65,0.1),vec2(0.76,0.4)),
sdSegment(p,vec2(0.85,0.12),vec2(0.76,0.41))),
sdSegment(p,vec2(0.75,0.6),vec2(0.76,0.43))),
sdSegment(p,vec2(0.75,0.6),vec2(0.9,0.52))),
sdSegment(p,vec2(0.75,0.6),vec2(0.6,0.56))),
sdCircle(p-vec2(0.73),0.08,0.035));
}

float sun(vec2 p) {
return min(min(min(
sdSegment(p,vec2(0.35,0.45),vec2(0.5,0.43)),
sdSegment(p,vec2(0.25,0.34),vec2(0.45,0.25))),
sdSegment(p,vec2(0.13,0.23),vec2(0.2,0.1))),
sdCircle(p-vec2(0.1,0.5),0.08,0.08));
}

float grass(vec2 p) {
return sdSegment(p+(vec2(0.0,sin(p.x*60.0)+sin(p.x*23.0)*0.1+fract((p.x+1.0)*10.0/pi))*0.05),vec2(0.0,0.2),vec2(2.0,0.2))-0.04;
}

float house(vec2 p) {
return min(min(min(min(min(min(min(min(
sdSegment(p,vec2(0.02,0.0),vec2(0.0,0.58)),
sdSegment(p,vec2(0.0,0.58),vec2(0.5,0.6))),
sdSegment(p,vec2(0.5,0.6),vec2(0.48,0.05))),
sdSegment(p,vec2(0.0,0.58),vec2(0.24,0.8))),
sdSegment(p,vec2(0.24,0.8),vec2(0.5,0.6))),
sdSegment(p,vec2(0.15,0.0),vec2(0.18,0.28))),
sdSegment(p,vec2(0.18,0.28),vec2(0.3,0.3))),
sdSegment(p,vec2(0.3),vec2(0.32,0.05))),
sdSegment(p,vec2(0.0),vec2(0.52,0.05)));
}

vec2 distort (vec2 p) {
return p+(vec2(sin(p.x*104.0+offset)+cos(p.y*113.0+offset))*0.0015);
}

float noise (vec2 p) {
	return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}

float smoothNoise(vec2 p)
{
    return noise(p)/4.0+(noise(p+vec2(1.0,0.0))+noise(p-vec2(1.0,0.0))+noise(p+vec2(0.0,1.0))+noise(p-vec2(0.0,1.0)))/8.0+(noise(p+vec2(1.0,1.0))+noise(p+vec2(1.0,-1.0))+noise(p-vec2(1.0,-1.0))+noise(p-vec2(1.0,1.0)))/16.0;
}

float COSInterpolation(float x,float y,float n)
{
    float r = n*pi;
    float f = (1.0-cos(r))*0.5;
    return x*(1.0-f)+y*f;
    
}

float InterpolationNoise(vec2 p)
{
    vec2 fracp = fract(p);    
    vec2 florp = floor(p);
    
    float v1 = smoothNoise(florp);
    float v2 = smoothNoise(florp+vec2(1.0,0.0));
    float v3 = smoothNoise(florp+vec2(0.0,1.0));
    float v4 = smoothNoise(florp+vec2(1.0,1.0));
    
   	float i1 = COSInterpolation(v1,v2,fracp.x);
    float i2 = COSInterpolation(v3,v4,fracp.x);
    
    return COSInterpolation(i1,i2,fracp.y);
    
}

float PerlinNoise2D(vec2 p)
{
    float sum = 0.0;
    float frequency =0.0;
    float amplitude = 0.0;
    for(int i=3;i<9;i++)
    {
        frequency = pow(2.0,float(i));
        amplitude = pow(0.6,float(i));
        sum = sum + InterpolationNoise(p*frequency)*amplitude;
    }
    
    return sum;
}

void main()
{
    vec2 uv = gl_FragCoord.xy/iResolution.xy;
    uv.x *= iResolution.x/iResolution.y;

    float grassv = min(min(min(
    grass(distort(uv)+vec2(0.0,0.1)),
    grass(distort(uv)+vec2(0.12,0.2))),
    grass(distort(uv)+vec2(0.08))),
    grass(distort(uv)+vec2(0.04)));
    
    float housev = house(distort(uv+vec2(0.03))-vec2(1.25,0.1));
    
    float childv = child(distort(uv-vec2(0.8,-0.06))+vec2(0.8,-0.06));
    
    float parent1 = parent(distort(uv-vec2(0.9,0.1))+vec2(0.9,0.1));
    
    float parent2 = parent(mat2(0.96,-0.1,0.1,0.96)*(distort(uv-vec2(0.22,-0.06))));
    
    float sunv = sun(distort(uv)+vec2(0.1,-0.5));
    
    gl_FragColor = vec4(0.9,0.9,0.95,0.1)*PerlinNoise2D(uv+vec2(5.0))*2.0+0.5;
    
    gl_FragColor = mix(gl_FragColor,vec4(0.8,0.8,0.03,1.0),clamp(sunv*-80.0+0.2,0.0,1.0)*PerlinNoise2D(distort(uv+vec2(1.0)+offset))*5.0*(smoothNoise(distort(uv+vec2(17.0)+mod(offset,100.0)))*0.2+0.6));
    gl_FragColor = mix(gl_FragColor,vec4(0.6,0.3,0.1,1.0),clamp(housev*-80.0+0.2,0.0,1.0)*PerlinNoise2D(distort(uv+vec2(2.0)+offset))*5.0*(smoothNoise(distort(uv+vec2(19.0)+mod(offset,100.0)))*0.2+0.6));
    gl_FragColor = mix(gl_FragColor,vec4(0.1,0.7,0.6,1.0),clamp(childv*-80.0+0.2,0.0,1.0)*PerlinNoise2D(distort(uv+vec2(3.0)+offset))*5.0*(smoothNoise(distort(uv+vec2(21.0)+mod(offset,100.0)))*0.2+0.6));
    gl_FragColor = mix(gl_FragColor,vec4(0.9,0.45,0.6,1.0),clamp(parent1*-80.0+0.2,0.0,1.0)*PerlinNoise2D(distort(uv+vec2(7.0)+offset))*5.0*(smoothNoise(distort(uv+vec2(23.0)+mod(offset,100.0)))*0.2+0.6));
    gl_FragColor = mix(gl_FragColor,vec4(0.33,0.5,0.77,1.0),clamp(parent2*-80.0+0.2,0.0,1.0)*PerlinNoise2D(distort(uv+vec2(11.0)+offset))*5.0*(smoothNoise(distort(uv+vec2(29.0)+mod(offset,100.0)))*0.2+0.6));
    gl_FragColor = mix(gl_FragColor,vec4(0.2,0.7,0.0,1.0),clamp(grassv*-30.0+0.2,0.0,1.0)*PerlinNoise2D(distort(uv+vec2(13.0)+offset))*5.0*(smoothNoise(distort(uv+vec2(31.0)+mod(offset,100.0)))*0.2+0.6));
    gl_FragColor = log(gl_FragColor+1.0)+0.15;
}