#ifdef GL_ES
precision mediump float;
#endif

#extension GL_OES_standard_derivatives : enable

#define SPEED 0.5
#define PI 3.14159265359
#define degToRad (PI * 2.0) / 360.0
#define fmod(x,y)  x-y*floor(x/y)


uniform float time;
uniform vec2 resolution;

struct Params {
	mat3 krot;
	mat3 lrot;
	mat3 staturot;
	float headSc;
	vec3 bodySc;
	float armSc;
	float legSc;
	float shoesSc;
	float floorSc;
	float statueSc;

	vec3 head;
	float bodyZ;
	float wallX;
	vec3 arm;
	vec3 leg;
	float shoesX;
	float shoesZ;
};

float random(vec2 n) { 
    return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
}

float randomRange (in vec2 seed, in float min, in float max) {
	return min + random(seed) * (max - min);
}	
	
float noise(vec2 p){
	const int res = 16;
	
	p *= float(res);
	vec2 n = floor(p);
	vec2 f = fract(p);
	
	f = f * f * (3.0 - 2.0 * f);
	
	float n0 = random(n);
	float n1 = random(n + vec2(1.0, 0.0));
	float n2 = random(n + vec2(0.0, 1.0));
	float n3 = random(n + vec2(1.0, 1.0));
	
	float m0 = mix(n0, n1, f.x);
	float m1 = mix(n2, n3, f.x);
	
	return mix(m0, m1, f.y);
}

mat3 matRotateY(float rad)
{
    return mat3(cos(rad), 0, -sin(rad),
					0, 1, 0,
					sin(rad), 0, cos(rad));
}

float opS( float d1, float d2 )
{
    return max(-d1,d2);
}

// Tunnel pattern studied from shane & shau
// i.e. https://www.shadertoy.com/view/4tKXzV
vec2 path(float t) {
    float a = sin(t*.2 + 1.5), b = sin(t*.2);
    return vec2(a*2., a*b);
}

float sdBox( vec3 p, vec3 b )
{
  vec3 d = abs(p) - b;
  return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}

float statue( vec3 p, vec2 h )
{
	const float a = 0.566025;
	p.y = abs(p.y);
    vec3 q = abs( p );
    float dx = max( q.x - h.y, max( q.z * a + p.y * 0.5, -p.y ) - h.x * 0.5 );
    float dz = max( q.z - h.y, max( q.x * a + p.y * 0.5, -p.y ) - h.x * 0.5 );
    return max( dx, dz );
}

vec4 combine(vec4 val1, vec4 val2 ){
    if ( val1.w < val2.w ) return val1;
    return val2;
}

float cubicInOut(float t) {
	float p = 2.0 * t * t;
	return t < 0.5 ? p : -p + (4.0 * t) - 1.0;
}

// A smart way to control the animation. function is from "http://qiita.com/gaziya5/items/29a51b066cb7d24983d6"
float animscene(in float t, float w, float s) {
    return clamp(t - w, 0.0, s) / s;  
}

vec3 bodyTex(vec3 cl,vec3 lcl,vec2 uv) {
	vec2 wave = vec2(uv.x,sin(uv.x*6.0*PI)/10.0-0.5 );
	float diff = distance(uv,wave)*noise(uv);
	return max(cl,smoothstep(0.1,0.01,diff))*lcl;
}

vec4 lilpumpDist(vec3 p, Params param){
	vec3 op=p;
    float d=100.0;
    
    p.x = abs(p.x);
    p -= vec3(0.35, 0.0, 0.0);
    p.y-=0.4;
    
    d=100.0;
    d = min(d,sdBox(p-vec3(0.0+param.leg.x,-0.65,0.9+param.leg.z),vec3(0.3+param.legSc,0.5,0.2)));
	vec4 leg = vec4(0.4,0.3,0.3,d);
    p=op;
    
    op=p;
    p.x = abs(p.x);
    p -= vec3(0.15, -1.15, 1.5);
    
    d=100.0;
	
	float shoes =sdBox(p+vec3(-0.2+param.shoesX,-0.4,0.6+param.shoesZ),vec3(0.32+param.shoesSc,0.08,0.3));
	d=min(d,shoes);
    vec4 shoesdist = vec4(0.75,0.75,0.75,d);
    p=op;
    
    op=p;
	p.y-=1.1;
    
    d=100.0;
    d=min(d,sdBox(p-vec3(0.0,-0.55+sin(time*5.1)*0.03,0.9+param.bodyZ),vec3(0.7+param.bodySc.x,0.6+param.bodySc.y,0.3+param.bodySc.z)));
	
	vec4 body = vec4(bodyTex(vec3(0.6,0.3,0.3),vec3(0.9,0.9,0.9),p.xy), d);
    p=op;
    
	op=p;
    p.x = abs(p.x);
    p -= vec3(0.86, 0.0, 0.0);
    p.y-=1.05;
    
    d=100.0;
    d=min(d, sdBox(p-vec3(0.0+param.arm.x,(-0.55+param.arm.y)+sin(time*5.0)*0.05,0.9+param.arm.z),vec3(0.15,0.65,0.3)));
	vec4 arm = vec4(0.55,0.3,0.3,d-0.0001);
    p=op;
    
	op=p;
	p.y-=1.65;
    
    d=100.0;
    d=min(d,sdBox((p-vec3(0.0,(-0.39+param.head.y)+sin(time*5.0)*0.05,0.9+param.head.z)),vec3(0.15+param.headSc,0.15+param.headSc,0.15+param.headSc)));
	vec4 head = vec4(0.95,0.75,0.6,d-0.0001);
    
    vec4 res1 = combine(leg,shoesdist);
    vec4 res2 = combine(body,arm);
    vec4 res3 = combine(head,res1);
    vec4 res4 = combine(res2,res3);

    return res4;
}

vec4 kanyeDist(vec3 p, Params param){
	vec3 op=p;
    float d=100.0;
    
    p.x = abs(p.x);
    p -= vec3(0.37, 0.0, 0.0);
    p.y-=0.4;
    
    d=100.0;
    d = min(d,sdBox(p-vec3(0.0+param.leg.x,-0.65,0.9+param.leg.z),vec3(0.3+param.legSc,0.5,0.2)));
	vec4 leg = vec4(0.3,0.3,0.3,d);
    p=op;
    
    op=p;
    p.x = abs(p.x);
    p -= vec3(0.15, -1.15, 1.9);
    
    d=100.0;
	float shoes =sdBox(p+vec3(-0.2+param.shoesX,-0.4,0.8+param.shoesZ),vec3(0.32+param.shoesSc,0.08,0.2));
	d=min(d,shoes);
    vec4 shoesdist = vec4(0.7,0.7,0.7,d);
    p=op;
    
    op=p;
	p.y-=1.1;
    
    d=100.0;
    d=min(d,sdBox(p-vec3(0.0,-0.55+sin(time*5.1)*0.03,0.9),vec3(0.7+param.bodySc.x,0.6+param.bodySc.y,0.3+param.bodySc.z)));
	vec4 body = vec4(bodyTex(vec3(0.2,0.07,0.05),vec3(0.5,0.37,0.0),p.xy), d);
    p=op;
    
	op=p;
    p.x = abs(p.x);
    p -= vec3(0.86, 0.0, 0.0);
    p.y-=1.05;
    
    d=100.0;
    d=min(d, sdBox((p-vec3(0.0+param.arm.x,(-0.55+param.arm.y)+sin(time*5.0)*0.05,0.9+param.arm.z)),vec3(0.15,0.65,0.3)));
	vec4 arm = vec4(0.12,0.05,0.05,d-0.0001);
    p=op;
    
	op=p;
	p.y-=1.65;
    
    d=100.0;
    d=min(d,sdBox(p-vec3(0.0,(-0.39+param.head.y)+sin(time*5.0)*0.05,0.9+param.head.z),vec3(0.15+param.headSc,0.15+param.headSc,0.15+param.headSc)));
	vec4 head = vec4(0.45,0.15,0.1,d-0.0001);

    vec4 res1 = combine(leg,shoesdist);
    vec4 res2 = combine(body,arm);
    vec4 res3 = combine(head,res1);
    vec4 res4 = combine(res2,res3);

    return res4;
}

vec3 noiseTex(vec3 p){
	vec3 color = vec3(0.0);
	color += noise(p.xz) * 0.125;
	color += noise(p.xz * 2.0) * 0.125;
	color += noise(p.xz * 4.0) * 0.125;
	color += noise(p.xz * 8.0) * 0.125;
	color += noise(p.xz * 16.0) * 0.125;
	color += noise(p.xz * 32.0) * 0.125;
	return color;
}

vec4 map(vec3 p,Params param){    
    float t = 100.0;
    
	vec3 oldp = p;
	p.z = mod(p.z+(time*SPEED), 0.5)-0.25;

    vec3 floorp = (p-vec3(0.0,0.5,0.0));
    float w = sdBox(floorp,vec3(3.6+param.floorSc, 0.01, 0.3));

	vec3 floorColor = noiseTex(floorp)*vec3(1.23);

    vec4 floorDist = vec4(floorColor, w);
    
    p = oldp;
    p.z = mod(p.z+(time*SPEED), 0.7)-0.35;
	p.x = abs(p.x);
    p -= vec3(6.0+param.wallX, 2.0, 0.0);
    
    
	float box = sdBox(p,vec3(0.3,3.5,0.5));
    float box2 = sdBox(p,vec3(0.5,1.5,0.2));
    float wall = opS(box2,box);
    
    t = min(t, wall);

	vec3 wallColor = noiseTex(p.zxy)*vec3(2.63,2.6,2.65);
    vec4 wallDist = vec4(wallColor, t);
    	
    t = 100.0;
    float sta = statue((p+vec3(0.2, 0.0, 0.0))*param.staturot,vec2(0.4+param.statueSc,0.1));
    t = min(t, sta);
    vec4 statueDist = vec4(0.85,0.82,0.85, t);
    
    t = 100.0;
    t = min(t, sdBox(p+vec3(0.3, 0.0, 0.35),vec3(0.02,3.5,0.02)));
    vec4 wallLine = vec4(0.9,0.9,0.9, t);
	
	vec4 lilpump = lilpumpDist((oldp+vec3(-1.5, -1.35, -7.0))*param.lrot,param);
	vec4 kanye = kanyeDist((oldp+vec3(1.5, -1.35, -6.0))*param.krot,param);

	vec4 res1 = combine(floorDist,wallDist);
    vec4 res2 = combine(statueDist,wallLine);
	vec4 res3 = combine(lilpump,kanye);
	vec4 res4 = combine(res1,res2);
	vec4 res5 = combine(res3,res4);

	return res5;
}

vec3 normalMap(vec3 p,Params param){
	float d = 0.0001;
	return normalize(vec3(
		map(p + vec3(  d, 0.0, 0.0),param).w - map(p + vec3( -d, 0.0, 0.0),param).w,
		map(p + vec3(0.0,   d, 0.0),param).w - map(p + vec3(0.0,  -d, 0.0),param).w,
		map(p + vec3(0.0, 0.0,   d),param).w - map(p + vec3(0.0, 0.0,  -d),param).w
	));
}

float shadowMap(vec3 ro, vec3 rd, Params param){
	float h = 0.0;
	float c = 0.001;
	float r = 1.0;
	float shadow = 0.5;
	for(float t = 0.0; t < 30.0; t++){
		h = map(ro + rd * c,param).w;
		if(h < 0.001){
			return shadow;
		}
		r = min(r, h * 16.0 / c);
		c += h;
	}
	return 1.0 - shadow + r * shadow;
}

void rainbow(vec2 p, float size, vec3 color, inout vec3 dst){
    float l = smoothstep(0.0,1.1,length(p - vec2( 0.0,  0.0)));
    if(l < size)dst = color;
}

float slopeSaw(vec2 position){
	float y = position.x;
	float animVal = sin(time);
	float animVal2 = sin(time*0.1);
	float animVal3 = sin(time*0.2);
	float animVal4 = sin(time*0.3);
	float animVal5 = sin(time*0.4);
	float animVal6 = sin(time*0.5);
	float animVal7 = sin(time*0.6);
	float animVal8 = sin(time*0.7);
	float animVal9 = sin(time*0.8);
	float slope = smoothstep( y-0.8+animVal, y-0.8+animVal, position.y);
	slope += smoothstep( y-0.6+animVal2, y-0.6+animVal2, position.y);
	slope += smoothstep( y-0.4+animVal4, y-0.4+animVal4, position.y);
	slope += smoothstep( y-0.2+animVal, y-0.2+animVal, position.y);
	slope += smoothstep( y+animVal5, y+animVal5, position.y);
	slope += smoothstep( y+0.2+animVal6, y+0.2+animVal6, position.y);
	slope += smoothstep( y+0.4+animVal7, y+0.4+animVal7, position.y);
	slope += smoothstep( y+0.6+animVal8, y+0.6+animVal8, position.y);
	slope += smoothstep( y+0.8+animVal9, y+0.8+animVal9, position.y);
	return slope;
}

void main(void){
	vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
	
	float uvy = mod(time*0.5,2.5)-1.0;
	if (p.y+uvy > 0.2 && p.y+uvy < 0.7) {
		p.x += sin(p.y*5.0)*0.1;
	}

	// glitch effects
	float sceneLength = 10.0;
	float scene = fmod(time,sceneLength);
	if(scene>7.0 && scene<8.0){
		float threshold = 0.3;

		float etime = sin(time)*70.0; 
		float f = fract(etime * 0.01* 10.0);
		etime += cubicInOut(2.0 - exp(-f*0.2));
		etime *= 0.2;
		float maxOffset = threshold/2.0;
		
		for(float i = 0.0; i < 10.0 * 0.3; i += 2.0){
			float sliceY = random(vec2(etime , float(i)));
			float sliceH = random(vec2(etime , float(i))) * 0.55;
			float hOffset = randomRange(vec2(etime , float(i)), -maxOffset, maxOffset);
			vec2 uvOff = p;
			uvOff.x += hOffset*etime*0.05;
			if ((step(-sliceY, p.y) - step(fract(-sliceY+sliceH), p.y)) == 1.0 ){
				p = uvOff;
			}
		}
		p.x += sin(p.y*etime)*0.2*cos(p.y*etime)*0.1;
	}	
	
	vec3 camPos = vec3(0.0, 2.0, 10.0);
	vec3 Fwd = vec3(0.0, 0.0, -1.0);
	vec3 Up  = vec3(0.0,  1., 0.0);
	
	vec3 left = cross(Fwd, Up);
	float depth = 0.7;
	vec3 ray = normalize(left * p.x + Up * p.y + Fwd * depth);

	float amplitude = 3.;
	float frequency = 2.;
	float noiseVal = 0.0;
	noiseVal = sin(frequency);
	float nt = 0.01*(-time*130.0);
	noiseVal += sin(p.x*frequency*2.1 + nt)*4.5;
	noiseVal += sin(p.x*frequency*1.72 + nt*1.121)*4.0;
	noiseVal += sin(p.x*frequency*2.221 + nt*0.437)*5.0;
	noiseVal += sin(p.x*frequency*3.1122+ nt*4.269)*2.5;
	noiseVal *= amplitude*0.06;

	p.xy -= path(noiseVal)*0.1;

	// animation
	mat3 camRotY = matRotateY(((sin(time*2.0)*noiseVal))*degToRad)*matRotateY(((sin(time*2.0)*3.0))*degToRad);
	mat3 rotY = matRotateY((22.0-(sin(time*2.0)*10.0))*degToRad);
	mat3 rotY2 = matRotateY((-20.0+(sin(time*2.2)*10.0))*degToRad);
	
	Params param;
	float animTime = fmod(time,16.0);
	float hsc = 0.0;
	hsc += cubicInOut(animscene(animTime, 1.0, 0.6))*0.2;
	hsc -= cubicInOut(animscene(animTime, 5.8, 0.6))*0.2;

	hsc += cubicInOut(animscene(animTime, 9.2, 0.6))*0.2;
	hsc -= cubicInOut(animscene(animTime, 12.9, 0.6))*0.2;

	float headY = 0.0;
	headY -= cubicInOut(animscene(animTime, 9.2, 0.6))*0.35;
	headY += cubicInOut(animscene(animTime, 12.9, 0.6))*0.35;
	
	float headZ = 0.0;
	headZ += cubicInOut(animscene(animTime, 9.2, 0.6))*0.5;
	headZ -= cubicInOut(animscene(animTime, 12.9, 0.6))*0.5;

	float bsc = 0.0;
	bsc -= cubicInOut(animscene(animTime, 1.4, 0.6))*0.35;
	bsc += cubicInOut(animscene(animTime, 5.4, 0.6))*0.35;

	bsc -= cubicInOut(animscene(animTime, 9.0, 0.6))*0.3;
	bsc += cubicInOut(animscene(animTime, 13.0, 0.6))*0.3;
	
	float bscY = 0.0;
	bscY -= cubicInOut(animscene(animTime, 9.1, 0.6))*0.2;
	bscY += cubicInOut(animscene(animTime, 13.1, 0.6))*0.2;

	float bscZ = 0.0;
	bscZ += cubicInOut(animscene(animTime, 9.2, 0.6))*0.35;
	bscZ -= cubicInOut(animscene(animTime, 13.2, 0.6))*0.35;

	float lsc = 0.0;
	lsc -= cubicInOut(animscene(animTime, 1.2, 0.6))*0.15;
	lsc += cubicInOut(animscene(animTime, 5.6, 0.6))*0.15;

	lsc -= cubicInOut(animscene(animTime, 8.9, 0.6))*0.15;
	lsc += cubicInOut(animscene(animTime, 12.9, 0.6))*0.15;

	float lx = 0.0;
	lx -= cubicInOut(animscene(animTime, 1.2, 0.6))*0.16;
	lx += cubicInOut(animscene(animTime, 5.6, 0.6))*0.16;

	lx -= cubicInOut(animscene(animTime, 8.9, 0.6))*0.16;
	lx += cubicInOut(animscene(animTime, 12.9, 0.6))*0.16;

	float lz = 0.0;
	lz -= cubicInOut(animscene(animTime, 8.9, 0.6))*0.4;
	lz += cubicInOut(animscene(animTime, 12.9, 0.6))*0.4;

	float shoessc = 0.0;
	shoessc -= cubicInOut(animscene(animTime, 1.3, 0.6))*0.16;
	shoessc += cubicInOut(animscene(animTime, 5.6, 0.6))*0.16;
	
	shoessc -= cubicInOut(animscene(animTime, 8.9, 0.6))*0.16;
	shoessc += cubicInOut(animscene(animTime, 12.9, 0.6))*0.16;

	float shoesx = 0.0;
	shoesx += cubicInOut(animscene(animTime, 1.3, 0.6))*0.16;
	shoesx -= cubicInOut(animscene(animTime, 5.6, 0.6))*0.16;

	shoesx += cubicInOut(animscene(animTime, 8.9, 0.6))*0.16;
	shoesx -= cubicInOut(animscene(animTime, 12.9, 0.6))*0.16;

	float shoesz = 0.0;
	shoesz += cubicInOut(animscene(animTime, 8.9, 0.6))*0.4;
	shoesz -= cubicInOut(animscene(animTime, 12.9, 0.6))*0.43;

	float armx = 0.0;
	armx -= cubicInOut(animscene(animTime, 1.7, 0.6))*0.35;
	armx += cubicInOut(animscene(animTime, 5.2, 0.6))*0.35;

	armx -= cubicInOut(animscene(animTime, 8.8, 0.6))*0.6;
	armx += cubicInOut(animscene(animTime, 12.8, 0.6))*0.6;

	float army = 0.0;
	army -= cubicInOut(animscene(animTime, 8.8, 0.6))*0.7;
	army += cubicInOut(animscene(animTime, 12.8, 0.6))*0.7;

	float armz = 0.0;
	armz += cubicInOut(animscene(animTime, 8.8, 0.6))*0.3;
	armz -= cubicInOut(animscene(animTime, 12.8, 0.6))*0.3;

	float fsc = 0.0;
	fsc -= cubicInOut(animscene(animTime, 2.0, 0.6))*0.6;
	fsc += cubicInOut(animscene(animTime, 6.2, 0.6))*0.6;

	fsc -= cubicInOut(animscene(animTime, 9.0, 0.6))*0.6;
	fsc += cubicInOut(animscene(animTime, 13.2, 0.6))*0.6;

	float wx = 0.0;
	wx -= cubicInOut(animscene(animTime, 2.3, 0.6))*0.6;
	wx += cubicInOut(animscene(animTime, 6.0, 0.6))*0.6;

	wx -= cubicInOut(animscene(animTime, 9.3, 0.6))*0.6;
	wx += cubicInOut(animscene(animTime, 13.0, 0.6))*0.6;

	float bgsc = 0.0;
	bgsc += cubicInOut(animscene(animTime, 1.9, 0.6))*0.3;
	bgsc -= cubicInOut(animscene(animTime, 5.8, 0.6))*0.3;

	bgsc += cubicInOut(animscene(animTime, 8.9, 0.6))*0.3;
	bgsc -= cubicInOut(animscene(animTime, 12.8, 0.6))*0.3;

	float staturot = 0.0;
	staturot += cubicInOut(animscene(animTime, 2.3, 1.0))*180.0;
	staturot += cubicInOut(animscene(animTime, 6.0, 1.0))*180.0;
	
	staturot += cubicInOut(animscene(animTime, 9.3, 1.0))*180.0;
	staturot += cubicInOut(animscene(animTime, 13.0, 1.0))*180.0;

	float statueSc = 0.4;
	statueSc -= cubicInOut(animscene(animTime, 2.3, 1.0))*0.4;
	statueSc += cubicInOut(animscene(animTime, 6.0, 1.0))*0.4;

	statueSc -= cubicInOut(animscene(animTime, 9.3, 1.0))*0.4;
	statueSc += cubicInOut(animscene(animTime, 13.0, 1.0))*0.4;

	param.krot = rotY;
	param.lrot = rotY2;
	param.staturot = matRotateY(staturot*degToRad);
	param.headSc = hsc;
	param.head = vec3(0,headY,headZ);
	param.bodySc = vec3(bsc,bscY,bscZ);
	param.legSc = lsc;
	param.leg = vec3(lx,0,lz);
	param.shoesSc = shoessc;
	param.shoesX = shoesx;
	param.shoesZ = shoesz;
	param.arm = vec3(armx,army,armz);
	param.floorSc = fsc;
	param.wallX = wx;
	param.statueSc = statueSc;

	float t, dist;
	t = 0.0;
	vec3 distPos = camPos;
	vec4 distCl = vec4(0.0);
	for(int i = 0; i < 60; i++){
		distCl = map(distPos,param);
		dist = distCl.w;
		if(dist < 0.001){break;}
		t += dist;
		distPos = (camPos + t * ray)*camRotY;
	}

	vec2 rainbowp = p;
	vec3 color;
	float shadow = 1.0;
	if(dist < 0.001){
		// lighting
		vec3 lightDir = vec3(0.0, 1.0, 0.0);
		vec3 light = normalize(lightDir + vec3(0.5, 0.0, 0.9));
		vec3 normal = normalMap(distPos,param);

		// difuse color
		float diffuse = clamp(dot(light, normal), 0.1, 1.0);
		float lambert = max(.0, dot( normal, light));
		
		// shadow
		shadow = shadowMap(distPos + normal * 0.001, light,param);

		// result
		color += vec3(lambert);
		color = diffuse*(distCl.xyz+(.1-length(p.xy)/3.))*vec3(1.0, 1.0, 1.0);
	}else{
		// rainbow bg
		if(scene>7.0 && scene<8.0){
			rainbowp.y+=slopeSaw((gl_FragCoord.xy) / min(resolution.x, resolution.y))-5.0;
		}
		
		rainbowp.x*=(0.55+bgsc);
		
		rainbowp.y += sin(rainbowp.x*30.0+time*2.0)*0.3*cos(rainbowp.x*10.0+time*2.0)*0.2;
		rainbowp.y += 0.05+(bgsc*0.2);
		

		vec3 rainbowbg = vec3(0.8)+(.1-length(p.xy)/3.);
		vec3 rcolor = rainbowbg;
		rainbow (rainbowp, 0.95, vec3(1.0,0.0,0.0), rcolor);
		rainbow (rainbowp, 0.9, vec3(1.0,0.6,0.0), rcolor);
		rainbow (rainbowp, 0.85, vec3(1.0,1.0,0.0), rcolor);
		rainbow (rainbowp, 0.8, vec3(0.0,1.0,0.0), rcolor);
		rainbow (rainbowp, 0.75, vec3(0.3,0.3,0.8), rcolor);
		rainbow (rainbowp, 0.7, vec3(0.7,0.7,1.0), rcolor);
		rainbow (rainbowp, 0.65, vec3(0.8,0.0,1.0), rcolor);
		rainbow (rainbowp, 0.6, rainbowbg, rcolor);

		color = rcolor*(rainbowbg*noiseTex(vec3(rainbowp.xy,rainbowp.y))*vec3(2.0));
	}

	// rendering result
	float brightness = 3.0;
	vec3 dst = (color * max(0.5, shadow))*brightness;
	gl_FragColor = vec4(dst, 1.0);

	// cross hatch
	vec3 hacthcolor = vec3(dst.x*0.9,0.2,0.2);
	float hatchsize = 5.0;
	if (color.g < 0.3) {
        if (mod(gl_FragCoord.x + gl_FragCoord.y, hatchsize) == 0.0) {
            gl_FragColor = vec4(hacthcolor, 1.0);
        }
    }
     
    if (color.g < 0.1) {
        if (mod(gl_FragCoord.x - gl_FragCoord.y, hatchsize) == 0.0) {
            gl_FragColor = vec4(hacthcolor, 1.0);
        }
    }

}