float makeBand(float d, float start, float end, float blur)
{
    float band1 = smoothstep(start - blur, start + blur, d);
    float band2 = smoothstep(end + blur, end - blur, d);
    return band1*band2;
}

float makeRect(vec2 uv, float left, float right, float top, float bottom, float blur)
{
    float verticalBand = makeBand(uv.x ,left,right,blur );
    float horizontalBand = makeBand(uv.y, bottom, top, blur);
    return verticalBand * horizontalBand;
}

float makeDiamond(vec2 uv, float left, float right, float top, float bottom, float blur)
{
    float verticalBand = makeBand(uv.x +uv.y ,left,right,blur );
    float horizontalBand = makeBand(uv.y - uv.x, bottom, top, blur);
    return verticalBand * horizontalBand;
}

float makeCircle(vec2 xy, float r, vec2 p, float blur)
{

    return (1.0f-smoothstep(r,  r*blur,length(p-xy)));

}

float makeSmileMask(vec2 xy, vec2 p, float r, float blur)
{
    float mask = 0.0f,mask_mouth=0.0f,mask_leftEye=0.0f,mask_rightEye=0.0f;
    //mask = makeCircle(xy,0.2f,vec2(0,0),1.1f);
    mask = makeCircle(xy,r,p,blur);
    mask_leftEye = makeCircle(xy,0.12f*r,vec2(p.x - 1.0f/3.0f*r,p.y + 1.0f/3.0f*r),1.5f*blur);
    mask_rightEye = makeCircle(xy,0.12f*r,vec2(p.x + 1.0f/3.0f*r,p.y + 1.0f/3.0f*r),1.5f*blur);
    mask_mouth = makeCircle( xy , 0.8f * r , p , blur) - makeCircle(xy,0.75f*r,vec2(p.x,0.2f * r+p.y),blur);
    mask -= (mask_leftEye + mask_rightEye + mask_mouth);
    return mask;
}



void makePalmTreeWithGround(inout vec3 col, in vec2 xy,in vec2 dToTreeOrigin,in float leafNum,in float originCircleRadius, in float palmTreeLengthOffset, in float bendLeafOffset)
{

 	//tree
    float r = originCircleRadius + palmTreeLengthOffset * cos(atan(dToTreeOrigin.y,dToTreeOrigin.x) * leafNum + bendLeafOffset * dToTreeOrigin.x + 2.0f * sin(iTime));
    col *= smoothstep(r - 0.02f, r, length(dToTreeOrigin));
    float branchEdgeWidth =  0.03f;
    //wave edge on the branch
    branchEdgeWidth += 0.01f + 0.0055f * cos(10.0f * dToTreeOrigin.y * 10.0f);
    //the ground
    branchEdgeWidth += 0.000001f * exp(-12.0f * dToTreeOrigin.y);
    //cut down upper part of the branch
    col *= 1.0f - (1.0f - smoothstep(branchEdgeWidth,branchEdgeWidth+0.02f,abs(dToTreeOrigin.x + 0.2f * sin(2.0f * dToTreeOrigin.y)))) * (1.0f - smoothstep(0.0f,0.1f,dToTreeOrigin.y));
}

float remap1(float a, float b, float t) //remap t to a - b in a range of 0-1
{
 	return ((t-a) / (b - a));
}

float remap2(float a , float b, float c, float d , float t)
{
    return remap1(a,b,t) * (d-c) + c;
}

float DistToLine(vec3 ro, vec3 rd, vec3 p)
{
 	return length(cross(p-ro,rd))/ length(rd);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    //make center of screen (0,0) and not affect by screen ratio
    vec2 xy = fragCoord / iResolution.xy;
    xy-=.5f;
    xy.x *= iResolution.x/ iResolution.y;
    vec3 ro = vec3(0,0,-2.0f);
    vec3 rd = vec3(xy.x,xy.y,0)- ro;
    float t =iTime;

    //first tree
    vec2 treeOrigin = vec2(0.3f,0.01f);
    vec2 dToTreeOrigin = xy - treeOrigin;
    dToTreeOrigin *=3.5f;

    //glowworm
    vec3 col_w = vec3(0.2,1.0f,0.0f);
    vec3 p = vec3(0.5f * sin(t),0.8f,2.0f + 3.0f * cos(t));
    p -= vec3(dToTreeOrigin.x - 0.8f , dToTreeOrigin.y+1.3f , 0);
    float dist_p = smoothstep(0.2f,0.1f,DistToLine(ro,rd,p));
    col_w *= dist_p;

    //Sun
    vec3 col = mix(vec3(0.2f, .6f, 1.0f), vec3(1.0f,0.7f,0.9f),5.0f*sin(2.0f*t+(-xy.x+xy.y)));
    vec2 rSunOrigin = vec2(-0.5,0.4f);
    vec2 vToSun = xy - rSunOrigin;
    vToSun *=5.5f;
    float dToSun = length(vToSun);

    //Second Tree
    vec2 secondTreeOrigin = vec2(0.6f,.8f);
    vec2 dToSTreeOrigin = xy - secondTreeOrigin;



    makePalmTreeWithGround(col, xy, dToTreeOrigin,10.0f,0.3f,0.2f,20.0f);

    makePalmTreeWithGround(col, xy, dToSTreeOrigin,5.0f,0.4f,0.2f,20.0f);

    //Sun
   	float r_Sun = 0.6f + 0.2f * cos(atan(vToSun.y,vToSun.x) * 10.0f + 20.0f * sin(t));
    col *= smoothstep(r_Sun - 0.02f, r_Sun, dToSun);

    //smile face
    float mask=0.0f;
    vec3 col_SmileFace = mix(vec3(1.0f,0.5f,0.2f),vec3(0.5f,1.0f,0.2f), sin(0.4f*t + xy.x));
    mask = makeSmileMask(xy,rSunOrigin,0.05f,1.1f);
	col_SmileFace*=mask;

    //jumping star
    float starMask = makeDiamond(xy-vec2(1.0f * sin(t),0.2f * abs(cos(t * 2.0f))) - vec2(0,-0.3f), -.03f * abs(sin(iTime)) , .03f* abs(sin(iTime)) ,.03f * abs(sin(iTime)),-.03f* abs(sin(iTime)), .002f);
    float star2Mask = makeRect(xy-vec2(1.0f * sin(t *1.5f),0.2f * abs(cos(t * 4.0f))) - vec2(0,-0.3f), -.04f * abs(sin(iTime)) , .04f* abs(sin(iTime)) ,.04f * abs(sin(iTime)),-.04f* abs(sin(iTime)), .002f);

    //river
    float riverX = xy.x;
    float riverY = xy.y;
    riverY +=0.42f;
    float m = 0.03f*sin(t+riverX*8.0f);
    riverY +=m;
    float blur = remap2(-.9f,.9f, 0.002f,0.05f,riverX);
    float riverMask = makeRect(vec2(riverX,riverY),-.9f,.9f, .01f,-.01f,blur);


    col += col_SmileFace+ starMask + star2Mask + riverMask +col_w ;

    fragColor = vec4(col,1.0f);
}

