<?xml version="1.0" encoding="UTF-8" ?>
<shader>
	<fragment><![CDATA[
		#version 150
		
		uniform vec4 water_Color;
		uniform vec4 water_FoamColor;
		uniform vec2 water_Time;

		smooth in vec2 frag_Parameter;

		out vec4 frag_Color;
		
		vec3 mod289(vec3 x) {
			return x - floor(x * (1.0 / 289.0)) * 289.0;
		}

		vec2 mod289(vec2 x) {
			return x - floor(x * (1.0 / 289.0)) * 289.0;
		}

		vec3 permute(vec3 x) {
			return mod289(((x*34.0)+1.0)*x);
		}

		float snoise(vec2 v)
		{
			const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
							  0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
							 -0.577350269189626, // -1.0 + 2.0 * C.x
							  0.024390243902439); // 1.0 / 41.0
			// First corner
			vec2 i = floor(v + dot(v, C.yy) );
			vec2 x0 = v - i + dot(i, C.xx);

			// Other corners
			vec2 i1;
			//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
			//i1.y = 1.0 - i1.x;
			i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
			// x0 = x0 - 0.0 + 0.0 * C.xx ;
			// x1 = x0 - i1 + 1.0 * C.xx ;
			// x2 = x0 - 1.0 + 2.0 * C.xx ;
			vec4 x12 = x0.xyxy + C.xxzz;
			x12.xy -= i1;

			// Permutations
			i = mod289(i); // Avoid truncation effects in permutation
			vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
			+ i.x + vec3(0.0, i1.x, 1.0 ));

			vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
			m = m*m ;
			m = m*m ;

			// Gradients: 41 points uniformly over a line, mapped onto a diamond.
			// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)

			vec3 x = 2.0 * fract(p * C.www) - 1.0;
			vec3 h = abs(x) - 0.5;
			vec3 ox = floor(x + 0.5);
			vec3 a0 = x - ox;

			// Normalise gradients implicitly by scaling m
			// Approximation of: m *= inversesqrt( a0*a0 + h*h );
			m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );

			// Compute final noise value at P
			vec3 g;
			g.x = a0.x * x0.x + h.x * x0.y;
			g.yz = a0.yz * x12.xz + h.yz * x12.yw;
			return 130.0 * dot(m, g);
		}

		void main()
		{
			vec2 f = frag_Parameter;
			float u = (sin(f.x) + 1.0) / 2.0;
			float v = (sin(f.y) + 1.0) / 2.0;
			float w = mix(0.7, 1.0, (u + v) / 2.0);
			
			float p1 = snoise(f + water_Time);
			float p2 = snoise(f - water_Time);
			float r = sqrt((cos((p1 - p2) * 3.14) + 1.0) / 2.0);
			
			if (r > 0.95)
			//if (a1 - a2 > (b1 + b2) * 2)
				frag_Color = vec4(water_FoamColor.rgb * w, water_Color.a);
			else
				frag_Color = vec4(water_Color.rgb * w, water_Color.a);
		}

	]]></fragment>
	<vertex><![CDATA[
		#version 150

		uniform mat4 water_Projection;
		uniform mat4 water_View;
		uniform vec2 water_Scale;
		uniform vec2 water_Offset;
		uniform float water_CurveFactor;
		uniform float water_Height;

		in vec2 water_Position;
		in vec2 water_Parameter;
		
		smooth out vec2 frag_Parameter;
		
		void main()
		{
			vec4 position = vec4
			(
				water_Position.x * water_Scale.x + water_Offset.x, 
				water_Height, 
				water_Position.y * water_Scale.y + water_Offset.y,
				1.0
			);
			
			vec4 p = water_View * position;
			
			if (water_CurveFactor > 0)
			{
				float z = (p.z + water_CurveFactor) / water_CurveFactor;
				p.y -= z * z;
			}
			
			gl_Position = water_Projection * p;
			
			frag_Parameter = water_Parameter * water_Scale;
		}
		]]></vertex>
</shader>
