var FXMultiBlobb = function () {

	FRAME.Module.call( this );

	this.parameters.input = {
	};

	var width = renderer.domElement.width;
	var height = renderer.domElement.height;

	var scene = new THREE.Scene();
	var camera = new THREE.OrthographicCamera(window.innerWidth / -2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / -2, -10, 10);
	var quadmaterial;
	var quad;

	this.init = function ( parameters ) {

		this.parameters.input = parameters;
	    var quadgeometry = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight);
	    
		this.quadmaterial = new THREE.ShaderMaterial({
	        uniforms: {
	                iGlobalTime: {
	                	type: "f",
	                	value: 1.0
	                },
	                iResolution: {
	                	type: "v2",
	                	value: new THREE.Vector2(renderer.getContext().drawingBufferWidth, renderer.getContext().drawingBufferHeight),
	                },
	        },
	        vertexShader: [

	                "varying vec2 vUv;",

	                "void main() {",

	                "vUv = vec2( uv.x, uv.y );",
	                "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",

	                "}"

	        ].join("\n"),
	        fragmentShader: [
"uniform float time;",
"uniform float iGlobalTime;",
"uniform vec2 iResolution;",
"varying vec2 vUv;",
"",
"",
"////////",
"// paste shadertoy here, begin",
"",
"",
"#define RM_MAX_ITER 20",
"#define DISTANCE 4",
"#define NBLOBf 3.",
"",
"const float eps = 0.01;",
"",
"vec3 rand3(float co){",
"    return fract(sin(co*vec3(12.9898,78.233,43.2311)) * 43758.5453);",
"}",
"",
"float multisphere(in vec3 p)",
"{",
"    float x = cos(iGlobalTime);",
"    ",
"    const float N = 2.;",
"    float l = 0.;",
"    vec3 f = rand3(1.);",
"    for (float i=1.; i<=NBLOBf; ++i)",
"    {",
"        vec3 q = sin(f*i*iGlobalTime);",
"        q = (q - 0.5)*0.75;",
"        l += 1./distance(p,q);",
"    }",
"    float r = 0.3;",
"    return 1./l - r;",
"}",
"",
"float sphere(in vec3 p, float r)",
"{",
"    return length(p) - r;",
"}",
"",
"float scene(in vec3 p)",
"{",
"//    float s1 = sphere(p,0.3);",
"//    float s2 = sphere(p+vec3(sin(iGlobalTime)*1.0,0.,0.),0.5);",
"    // return sqrt(s1*s1 + s2*s2);",
"//    return min(s1,s2);",
"    //return (s1+s2)*0.5;",
"    float s3 = multisphere(p);",
"//    return min(s1,s3);",
"    return s3;",
"}",
"",
"// gradient normal",
"vec3 getNormal(in vec3 p)",
"{",
"    vec3 normal;",
"    vec3 ep = vec3(eps,0,0);",
"    normal.x = scene(p + ep.xyz) - scene(p - ep.xyz);",
"    normal.y = scene(p + ep.yxz) - scene(p - ep.yxz);",
"    normal.z = scene(p + ep.yzx) - scene(p - ep.yzx);",
"    return normalize(normal);",
"}",
"",
"void mainImage( out vec4 fragColor, in vec2 fragCoord )",
"{",
"	vec2 uv = (fragCoord.xy - iResolution.xy*0.5) / iResolution.yy;    ",
"    ",
"    vec3 rayStart = vec3(0,0,DISTANCE);",
"    vec3 rayDir = normalize(vec3(uv,-1));",
"    ",
"    float a = 0.4*iGlobalTime;",
"    float ca = cos(a);",
"    float sa = sin(a);",
"    rayStart = vec3(rayStart.z*sa + rayStart.x*ca, rayStart.y, rayStart.z*ca - rayStart.x*sa);",
"    rayDir = vec3(rayDir.z*sa + rayDir.x*ca, rayDir.y, rayDir.z*ca - rayDir.x*sa);",
"    ",
"    vec3 p;",
"    float t = 0.0;",
"    float dist;",
"    for (int i=0; i<RM_MAX_ITER; ++i)",
"    {",
"        p = rayStart + rayDir*t;",
"        dist = scene(p);",
"		t += dist;",
"    }",
"",
"    vec3 finalColor = vec3(0,0,0);",
"    vec3 normal = getNormal(p.xyz);",
"    //vec3 normal = vec3(0,0,1);",
"    vec3 light1 = vec3(sin(iGlobalTime),cos(iGlobalTime),0);",
"    vec3 light2 = vec3(0,0,1);",
"    //            finalColor = normal;",
"    //            finalColor = vec3(1,0,1) *",
"    //                dot(vec3(1.,sin(iGlobalTime ),cos(iGlobalTime )),normal);",
"    float diffuse1 = dot(light1,normal);",
"    float diffuse2 = dot(light2,normal);",
"    float specular = pow(max(0.,dot(light1,normal)),11.);",
"   /*         if (dist>1.*eps)",
"{",
"diffuse1 *= 0.1;",
"diffuse2 *= 0.1;",
"}*/",
"",
"    //float specular = 0.;",
"    float ambient = 0.2;",
"    finalColor = vec3(1,0,1) *",
"        (0.5* diffuse1 + 0.5*diffuse2 + specular);",
"    ",
"	dist = clamp(clamp(dist*10.,0.,1.)-length(finalColor),0.,1.);",
"	vec3 backColor = vec3(1., 1., 1.);",
"	fragColor = vec4(mix(finalColor,backColor,dist), 1.);",
"}",
"",
"",
"",
"// paste shadertoy here, stop",
"////////",
"",
"void main()",
"{",
"	vec4 fragColor;",
"	vec2 fragCoord = vUv.xy*iResolution;",
"",
"	mainImage(fragColor,fragCoord);",
"    ",
"	gl_FragColor = fragColor;",
"}",
""].join("\n"),
			depthTest: false,
			depthWrite: false,
			blending: THREE.AdditiveBlending 
	    });

		//quad = new THREE.Mesh(quadgeometry, this.quadmaterial, this.compositeShader);
		quad = new THREE.Mesh(quadgeometry, this.quadmaterial);
    	scene.add(quad);

		camera = new THREE.OrthographicCamera(window.innerWidth / -2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / -2, -100, 100);
	};

	this.start = function ( t, parameters ) {

	};

	this.end = function ( ) {
		
	};	

	this.update = function ( t, perc ) {		
	    quad.material.uniforms['iGlobalTime'].value = t;

	    renderer.render( scene, camera );
	};

};