/*
 * Voronoi by rimina
 */

THREE.Voronoi = {

	uniforms: {
		"uTime" : { type: "f", value: 0.0},
		"uResolution" : {type: "v2", value: new THREE.Vector2(0, 0)},
	},

	vertexShader: [

		"varying vec2 vUv;",
		"void main() {",
			"vUv = uv;",
			"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
		"}"

	].join("\n"),

	fragmentShader: [
		"#include <packing>",
		"uniform float uTime;",
		"uniform vec2 uResolution;",

        "varying vec2 vUv;",

		//Hash method from https://www.shadertoy.com/view/4djSRW
		"#define HASHSCALE3 vec3(.1031, .1030, .0973)",

		"vec2 Hash22F(vec2  p ){",
			"vec3 p3 = fract(vec3(p.xyx ) * HASHSCALE3);", 
			"p3 += dot(p3, p3.yzx  + 19.19);",
			"return fract((p3.xx   + p3.yz  ) * p3.zy  );",
		"}",

		"float voronoi(vec2 q, inout vec2 mm){",
			"vec2 qq = q * 5.0;",
			"vec2 f = fract(qq);",
			"vec2 i = floor(qq);",
			"float m = 1.0;",
			"mm = vec2(1.0);",

			"for(int y = -1; y <= 1; ++y){",
				"for(int x = -1; x <= 1; ++x){",
					"vec2 neighbor = vec2(float(x), float(y));",
					"vec2 point = Hash22F(i + neighbor);",

					"point = 0.5 + 0.5*sin(uTime*10.5 + 9.0 * point);",

					"float d = length(neighbor + point - f);",
					"if(d < m){",
						"m = d;",
						"mm = point;",
					"}",
				"}",
			"}",

			"return m;",
		"}",

		"void main(){",
			"vec2 q = -1.0 + vUv*2.0;",
			"q.x *= uResolution.x/uResolution.y;",

			"vec3 col = vec3(0.0);",
			"vec2 mm = vec2(1.0);",
			"float m = voronoi(q, mm);",
			"col.rb = mm;",
			"col = step(0.5, col);",
			"col = col.bbb;",
            "col += vec3(0.0, 1.2, 1.2);",
            "col = vec3(1.0)-col;",
            "col = smoothstep(-0.2, 1.2, col);",

			"gl_FragColor = vec4(col, 1.0);",
		"}"

	].join("\n")

};
