/*
								+--------------------------------+
								|								 |
								|   ***    OpenGL Noise    ***   |
								|								 |
								|  Copyright © -tHE SWINe- 2012	 |
								|								 |
								|			GLNoise.h			 |
								|								 |
								+--------------------------------+
*/

#pragma once
#ifndef __GLSL_NOISE_SOURCE_INCLUDED
#define __GLSL_NOISE_SOURCE_INCLUDED

/**
 *	@file gl3/GLNoise.h
 *	@author -tHE SWINe-
 *	@brief OpenGL ES noise function implementations
 *	@date 2012
 *
 *	These shaders are taken from https://github.com/ashima/webgl-noise and
 *		from http://webstaff.itn.liu.se/~stegu/GLSL-cellular/.
 *	The authors are Stefan Gustavson and Ian McEwan.
 *	These source codes were modified to be suitable for multiple
 *	noise function inclusion in a single shader, and simple use.
 *
 *	Note that all these functions are tableless, i.e. these do not require
 *	any textures or uniform arrays, just include the source code is enough.
 *
 *	See shader sources below for respective license / copyright notice.
 *
 *	To include noise functions in shader source, simply concatenate
 *	with one or more of:
 *
 *		GL_CLASSIC_NOISE_2D_SRC
 *		GL_CLASSIC_NOISE_3D_SRC
 *		GL_CLASSIC_NOISE_4D_SRC
 *
 *		GL_SIMPLEX_NOISE_2D_SRC
 *		GL_SIMPLEX_NOISE_3D_SRC
 *		GL_SIMPLEX_NOISE_4D_SRC
 *
 *		GL_CELL_NOISE_2D_SRC
 *		GL_CELL_NOISE_2D_FAST_SRC
 *		GL_CELL_NOISE_3D_SRC
 *		GL_CELL_NOISE_3D_FAST_SRC
 *
 *		GL_FLOW_NOISE_2D_SRC
 *
 *	One might also want to use:
 *
 *		GL_SIMPLEX_NOISE_ALL_SRC
 *		GL_CLASSIC_NOISE_ALL_SRC
 *		GL_CELL_NOISE_ALL_SRC
 *		GL_FLOW_NOISE_ALL_SRC
 *		GL_ALL_NOISE_ALL_SRC
 *
 *	Note that these are bare constant "C" strings, one can therefore
 *	concatenate them with other such strings at compile time.
 *
 */

/*
 *	Copyright (C) 2011 by Ashima Arts (Simplex noise)
 *	Copyright (C) 2011 by Stefan Gustavson (Classic noise)
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a copy
 *	of this software and associated documentation files (the "Software"), to deal
 *	in the Software without restriction, including without limitation the rights
 *	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the Software is
 *	furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in
 *	all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *	THE SOFTWARE.
 */

/*
 *	GLSL 2D and 3D cellular noise
 *	Copyright (c) 2011 by Stefan Gustavson (stefan.gustavson@liu.se)
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a copy
 *	of this software and associated documentation files (the "Software"), to deal
 *	in the Software without restriction, including without limitation the rights
 *	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the Software is
 *	furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in
 *	all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *	THE SOFTWARE.
 */

/*
 *	GLSL 2D flow noise
 *	Copyright (C) 2011 by Stefan Gustavson
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a copy
 *	of this software and associated documentation files (the "Software"), to deal
 *	in the Software without restriction, including without limitation the rights
 *	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the Software is
 *	furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in
 *	all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *	THE SOFTWARE.
 */

/**
 *	@def GL_CLASSIC_NOISE_2D_SRC
 *	@brief classic 2D Perlin noise cnoise() and its periodic variant pnoise()
 */
#define GL_CLASSIC_NOISE_2D_SRC \
	"//\n" \
	"// GLSL textureless classic 2D noise \"cnoise\",\n" \
	"// with an RSL-style periodic variant \"pnoise\".\n" \
	"// Author: Stefan Gustavson (stefan.gustavson@liu.se)\n" \
	"// Version: 2011-08-22\n" \
	"//\n" \
	"// Many thanks to Ian McEwan of Ashima Arts for the\n" \
	"// ideas for permutation and gradient selection.\n" \
	"//\n" \
	"// Copyright (c) 2011 Stefan Gustavson. All rights reserved.\n" \
	"// Distributed under the MIT license. See LICENSE file.\n" \
	"// https://github.com/ashima/webgl-noise\n" \
	"//\n" \
	"\n" \
	"#ifndef __PNOISE_CLASSIC_2D\n" \
	"#define __PNOISE_CLASSIC_2D\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC4\n" \
	"#define __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"vec4 mod289(vec4 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_PERMUTE_VEC4\n" \
	"#define __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"vec4 permute(vec4 x)\n" \
	"{\n" \
	"	return mod289(((x * 34.0) + 1.0) * x);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_RSQRT_VEC4\n" \
	"#define __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"vec4 taylorInvSqrt(vec4 r)\n" \
	"{\n" \
	"	return 1.79284291400159 - 0.85373472095314 * r;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_FADE_VEC2\n" \
	"#define __PNOISE_FADE_VEC2\n" \
	"\n" \
	"vec2 fade(vec2 t)\n" \
	"{\n" \
	"	return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_FADE_VEC2\n" \
	"\n" \
	"/**\n" \
	" *	@brief Classic Perlin noise\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float cnoise(vec2 P)\n" \
	"{\n" \
	"	vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);\n" \
	"	vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);\n" \
	"	Pi = mod289(Pi); // To avoid truncation effects in permutation\n" \
	"	vec4 ix = Pi.xzxz;\n" \
	"	vec4 iy = Pi.yyww;\n" \
	"	vec4 fx = Pf.xzxz;\n" \
	"	vec4 fy = Pf.yyww;\n" \
	"\n" \
	"	vec4 i = permute(permute(ix) + iy);\n" \
	"\n" \
	"	vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0;\n" \
	"	vec4 gy = abs(gx) - 0.5;\n" \
	"	vec4 tx = floor(gx + 0.5);\n" \
	"	gx = gx - tx;\n" \
	"\n" \
	"	vec2 g00 = vec2(gx.x, gy.x);\n" \
	"	vec2 g10 = vec2(gx.y, gy.y);\n" \
	"	vec2 g01 = vec2(gx.z, gy.z);\n" \
	"	vec2 g11 = vec2(gx.w, gy.w);\n" \
	"\n" \
	"	vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));\n" \
	"	g00 *= norm.x;\n" \
	"	g01 *= norm.y;\n" \
	"	g10 *= norm.z;\n" \
	"	g11 *= norm.w;\n" \
	"\n" \
	"	float n00 = dot(g00, vec2(fx.x, fy.x));\n" \
	"	float n10 = dot(g10, vec2(fx.y, fy.y));\n" \
	"	float n01 = dot(g01, vec2(fx.z, fy.z));\n" \
	"	float n11 = dot(g11, vec2(fx.w, fy.w));\n" \
	"\n" \
	"	vec2 fade_xy = fade(Pf.xy);\n" \
	"	vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);\n" \
	"	float n_xy = mix(n_x.x, n_x.y, fade_xy.y);\n" \
	"	return 2.3 * n_xy;\n" \
	"}\n" \
	"\n" \
	"/**\n" \
	" *	@brief Classic Perlin noise, periodic variant\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@param[in] rep is period\n" \
	" *\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float pnoise(vec2 P, vec2 rep)\n" \
	"{\n" \
	"	vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);\n" \
	"	vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);\n" \
	"	Pi = mod(Pi, rep.xyxy); // To create noise with explicit period\n" \
	"	Pi = mod289(Pi); // To avoid truncation effects in permutation\n" \
	"	vec4 ix = Pi.xzxz;\n" \
	"	vec4 iy = Pi.yyww;\n" \
	"	vec4 fx = Pf.xzxz;\n" \
	"	vec4 fy = Pf.yyww;\n" \
	"\n" \
	"	vec4 i = permute(permute(ix) + iy);\n" \
	"\n" \
	"	vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0;\n" \
	"	vec4 gy = abs(gx) - 0.5;\n" \
	"	vec4 tx = floor(gx + 0.5);\n" \
	"	gx = gx - tx;\n" \
	"\n" \
	"	vec2 g00 = vec2(gx.x, gy.x);\n" \
	"	vec2 g10 = vec2(gx.y, gy.y);\n" \
	"	vec2 g01 = vec2(gx.z, gy.z);\n" \
	"	vec2 g11 = vec2(gx.w, gy.w);\n" \
	"\n" \
	"	vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));\n" \
	"	g00 *= norm.x;\n" \
	"	g01 *= norm.y;\n" \
	"	g10 *= norm.z;\n" \
	"	g11 *= norm.w;\n" \
	"\n" \
	"	float n00 = dot(g00, vec2(fx.x, fy.x));\n" \
	"	float n10 = dot(g10, vec2(fx.y, fy.y));\n" \
	"	float n01 = dot(g01, vec2(fx.z, fy.z));\n" \
	"	float n11 = dot(g11, vec2(fx.w, fy.w));\n" \
	"\n" \
	"	vec2 fade_xy = fade(Pf.xy);\n" \
	"	vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);\n" \
	"	float n_xy = mix(n_x.x, n_x.y, fade_xy.y);\n" \
	"	return 2.3 * n_xy;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_CLASSIC_2D\n" \
	"\n"

/**
 *	@def GL_CLASSIC_NOISE_3D_SRC
 *	@brief classic 3D Perlin noise cnoise() and its periodic variant pnoise()
 */
#define GL_CLASSIC_NOISE_3D_SRC \
	"//\n" \
	"// GLSL textureless classic 3D noise \"cnoise\",\n" \
	"// with an RSL-style periodic variant \"pnoise\".\n" \
	"// Author: Stefan Gustavson (stefan.gustavson@liu.se)\n" \
	"// Version: 2011-10-11\n" \
	"//\n" \
	"// Many thanks to Ian McEwan of Ashima Arts for the\n" \
	"// ideas for permutation and gradient selection.\n" \
	"//\n" \
	"// Copyright (c) 2011 Stefan Gustavson. All rights reserved.\n" \
	"// Distributed under the MIT license. See LICENSE file.\n" \
	"// https://github.com/ashima/webgl-noise\n" \
	"//\n" \
	"\n" \
	"#ifndef __PNOISE_CLASSIC_3D\n" \
	"#define __PNOISE_CLASSIC_3D\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC3\n" \
	"#define __PNOISE_MOD289_VEC3\n" \
	"\n" \
	"vec3 mod289(vec3 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC3\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC4\n" \
	"#define __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"vec4 mod289(vec4 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_PERMUTE_VEC4\n" \
	"#define __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"vec4 permute(vec4 x)\n" \
	"{\n" \
	"	return mod289(((x*34.0)+1.0)*x);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_RSQRT_VEC4\n" \
	"#define __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"vec4 taylorInvSqrt(vec4 r)\n" \
	"{\n" \
	"	return 1.79284291400159 - 0.85373472095314 * r;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_FADE_VEC3\n" \
	"#define __PNOISE_FADE_VEC3\n" \
	"\n" \
	"vec3 fade(vec3 t)\n" \
	"{\n" \
	"	return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_FADE_VEC3\n" \
	"\n" \
	"/**\n" \
	" *	@brief Classic Perlin noise\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float cnoise(vec3 P)\n" \
	"{\n" \
	"	vec3 Pi0 = floor(P); // Integer part for indexing\n" \
	"	vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1\n" \
	"	Pi0 = mod289(Pi0);\n" \
	"	Pi1 = mod289(Pi1);\n" \
	"	vec3 Pf0 = fract(P); // Fractional part for interpolation\n" \
	"	vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0\n" \
	"	vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);\n" \
	"	vec4 iy = vec4(Pi0.yy, Pi1.yy);\n" \
	"	vec4 iz0 = Pi0.zzzz;\n" \
	"	vec4 iz1 = Pi1.zzzz;\n" \
	"\n" \
	"	vec4 ixy = permute(permute(ix) + iy);\n" \
	"	vec4 ixy0 = permute(ixy + iz0);\n" \
	"	vec4 ixy1 = permute(ixy + iz1);\n" \
	"\n" \
	"	vec4 gx0 = ixy0 * (1.0 / 7.0);\n" \
	"	vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;\n" \
	"	gx0 = fract(gx0);\n" \
	"	vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);\n" \
	"	vec4 sz0 = step(gz0, vec4(0.0));\n" \
	"	gx0 -= sz0 * (step(0.0, gx0) - 0.5);\n" \
	"	gy0 -= sz0 * (step(0.0, gy0) - 0.5);\n" \
	"\n" \
	"	vec4 gx1 = ixy1 * (1.0 / 7.0);\n" \
	"	vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;\n" \
	"	gx1 = fract(gx1);\n" \
	"	vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);\n" \
	"	vec4 sz1 = step(gz1, vec4(0.0));\n" \
	"	gx1 -= sz1 * (step(0.0, gx1) - 0.5);\n" \
	"	gy1 -= sz1 * (step(0.0, gy1) - 0.5);\n" \
	"\n" \
	"	vec3 g000 = vec3(gx0.x, gy0.x, gz0.x);\n" \
	"	vec3 g100 = vec3(gx0.y, gy0.y, gz0.y);\n" \
	"	vec3 g010 = vec3(gx0.z, gy0.z, gz0.z);\n" \
	"	vec3 g110 = vec3(gx0.w, gy0.w, gz0.w);\n" \
	"	vec3 g001 = vec3(gx1.x, gy1.x, gz1.x);\n" \
	"	vec3 g101 = vec3(gx1.y, gy1.y, gz1.y);\n" \
	"	vec3 g011 = vec3(gx1.z, gy1.z, gz1.z);\n" \
	"	vec3 g111 = vec3(gx1.w, gy1.w, gz1.w);\n" \
	"\n" \
	"	vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));\n" \
	"	g000 *= norm0.x;\n" \
	"	g010 *= norm0.y;\n" \
	"	g100 *= norm0.z;\n" \
	"	g110 *= norm0.w;\n" \
	"	vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));\n" \
	"	g001 *= norm1.x;\n" \
	"	g011 *= norm1.y;\n" \
	"	g101 *= norm1.z;\n" \
	"	g111 *= norm1.w;\n" \
	"\n" \
	"	float n000 = dot(g000, Pf0);\n" \
	"	float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));\n" \
	"	float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));\n" \
	"	float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));\n" \
	"	float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));\n" \
	"	float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));\n" \
	"	float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));\n" \
	"	float n111 = dot(g111, Pf1);\n" \
	"\n" \
	"	vec3 fade_xyz = fade(Pf0);\n" \
	"	vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);\n" \
	"	vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);\n" \
	"	float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);\n" \
	"	return 2.2 * n_xyz;\n" \
	"}\n" \
	"\n" \
	"/**\n" \
	" *	@brief Classic Perlin noise, periodic variant\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@param[in] rep is period\n" \
	" *\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float pnoise(vec3 P, vec3 rep)\n" \
	"{\n" \
	"	vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period\n" \
	"	vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period\n" \
	"	Pi0 = mod289(Pi0);\n" \
	"	Pi1 = mod289(Pi1);\n" \
	"	vec3 Pf0 = fract(P); // Fractional part for interpolation\n" \
	"	vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0\n" \
	"	vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);\n" \
	"	vec4 iy = vec4(Pi0.yy, Pi1.yy);\n" \
	"	vec4 iz0 = Pi0.zzzz;\n" \
	"	vec4 iz1 = Pi1.zzzz;\n" \
	"\n" \
	"	vec4 ixy = permute(permute(ix) + iy);\n" \
	"	vec4 ixy0 = permute(ixy + iz0);\n" \
	"	vec4 ixy1 = permute(ixy + iz1);\n" \
	"\n" \
	"	vec4 gx0 = ixy0 * (1.0 / 7.0);\n" \
	"	vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;\n" \
	"	gx0 = fract(gx0);\n" \
	"	vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);\n" \
	"	vec4 sz0 = step(gz0, vec4(0.0));\n" \
	"	gx0 -= sz0 * (step(0.0, gx0) - 0.5);\n" \
	"	gy0 -= sz0 * (step(0.0, gy0) - 0.5);\n" \
	"\n" \
	"	vec4 gx1 = ixy1 * (1.0 / 7.0);\n" \
	"	vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;\n" \
	"	gx1 = fract(gx1);\n" \
	"	vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);\n" \
	"	vec4 sz1 = step(gz1, vec4(0.0));\n" \
	"	gx1 -= sz1 * (step(0.0, gx1) - 0.5);\n" \
	"	gy1 -= sz1 * (step(0.0, gy1) - 0.5);\n" \
	"\n" \
	"	vec3 g000 = vec3(gx0.x, gy0.x, gz0.x);\n" \
	"	vec3 g100 = vec3(gx0.y, gy0.y, gz0.y);\n" \
	"	vec3 g010 = vec3(gx0.z, gy0.z, gz0.z);\n" \
	"	vec3 g110 = vec3(gx0.w, gy0.w, gz0.w);\n" \
	"	vec3 g001 = vec3(gx1.x, gy1.x, gz1.x);\n" \
	"	vec3 g101 = vec3(gx1.y, gy1.y, gz1.y);\n" \
	"	vec3 g011 = vec3(gx1.z, gy1.z, gz1.z);\n" \
	"	vec3 g111 = vec3(gx1.w, gy1.w, gz1.w);\n" \
	"\n" \
	"	vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));\n" \
	"	g000 *= norm0.x;\n" \
	"	g010 *= norm0.y;\n" \
	"	g100 *= norm0.z;\n" \
	"	g110 *= norm0.w;\n" \
	"	vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));\n" \
	"	g001 *= norm1.x;\n" \
	"	g011 *= norm1.y;\n" \
	"	g101 *= norm1.z;\n" \
	"	g111 *= norm1.w;\n" \
	"\n" \
	"	float n000 = dot(g000, Pf0);\n" \
	"	float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));\n" \
	"	float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));\n" \
	"	float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));\n" \
	"	float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));\n" \
	"	float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));\n" \
	"	float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));\n" \
	"	float n111 = dot(g111, Pf1);\n" \
	"\n" \
	"	vec3 fade_xyz = fade(Pf0);\n" \
	"	vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);\n" \
	"	vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);\n" \
	"	float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);\n" \
	"	return 2.2 * n_xyz;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_CLASSIC_3D\n" \
	"\n"

/**
 *	@def GL_CLASSIC_NOISE_4D_SRC
 *	@brief classic 4D Perlin noise cnoise() and its periodic variant pnoise()
 */
#define GL_CLASSIC_NOISE_4D_SRC \
	"//\n" \
	"// GLSL textureless classic 4D noise \"cnoise\",\n" \
	"// with an RSL-style periodic variant \"pnoise\".\n" \
	"// Author: Stefan Gustavson (stefan.gustavson@liu.se)\n" \
	"// Version: 2011-08-22\n" \
	"//\n" \
	"// Many thanks to Ian McEwan of Ashima Arts for the\n" \
	"// ideas for permutation and gradient selection.\n" \
	"//\n" \
	"// Copyright (c) 2011 Stefan Gustavson. All rights reserved.\n" \
	"// Distributed under the MIT license. See LICENSE file.\n" \
	"// https://github.com/ashima/webgl-noise\n" \
	"//\n" \
	"\n" \
	"#ifndef __PNOISE_CLASSIC_4D\n" \
	"#define __PNOISE_CLASSIC_4D\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC4\n" \
	"#define __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"vec4 mod289(vec4 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_PERMUTE_VEC4\n" \
	"#define __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"vec4 permute(vec4 x)\n" \
	"{\n" \
	"	return mod289(((x*34.0)+1.0)*x);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_RSQRT_VEC4\n" \
	"#define __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"vec4 taylorInvSqrt(vec4 r)\n" \
	"{\n" \
	"	return 1.79284291400159 - 0.85373472095314 * r;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_FADE_VEC4\n" \
	"#define __PNOISE_FADE_VEC4\n" \
	"\n" \
	"vec4 fade(vec4 t)\n" \
	"{\n" \
	"	return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_FADE_VEC4\n" \
	"\n" \
	"/**\n" \
	" *	@brief Classic Perlin noise\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float cnoise(vec4 P)\n" \
	"{\n" \
	"	vec4 Pi0 = floor(P); // Integer part for indexing\n" \
	"	vec4 Pi1 = Pi0 + 1.0; // Integer part + 1\n" \
	"	Pi0 = mod289(Pi0);\n" \
	"	Pi1 = mod289(Pi1);\n" \
	"	vec4 Pf0 = fract(P); // Fractional part for interpolation\n" \
	"	vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0\n" \
	"	vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);\n" \
	"	vec4 iy = vec4(Pi0.yy, Pi1.yy);\n" \
	"	vec4 iz0 = vec4(Pi0.zzzz);\n" \
	"	vec4 iz1 = vec4(Pi1.zzzz);\n" \
	"	vec4 iw0 = vec4(Pi0.wwww);\n" \
	"	vec4 iw1 = vec4(Pi1.wwww);\n" \
	"\n" \
	"	vec4 ixy = permute(permute(ix) + iy);\n" \
	"	vec4 ixy0 = permute(ixy + iz0);\n" \
	"	vec4 ixy1 = permute(ixy + iz1);\n" \
	"	vec4 ixy00 = permute(ixy0 + iw0);\n" \
	"	vec4 ixy01 = permute(ixy0 + iw1);\n" \
	"	vec4 ixy10 = permute(ixy1 + iw0);\n" \
	"	vec4 ixy11 = permute(ixy1 + iw1);\n" \
	"\n" \
	"	vec4 gx00 = ixy00 * (1.0 / 7.0);\n" \
	"	vec4 gy00 = floor(gx00) * (1.0 / 7.0);\n" \
	"	vec4 gz00 = floor(gy00) * (1.0 / 6.0);\n" \
	"	gx00 = fract(gx00) - 0.5;\n" \
	"	gy00 = fract(gy00) - 0.5;\n" \
	"	gz00 = fract(gz00) - 0.5;\n" \
	"	vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00);\n" \
	"	vec4 sw00 = step(gw00, vec4(0.0));\n" \
	"	gx00 -= sw00 * (step(0.0, gx00) - 0.5);\n" \
	"	gy00 -= sw00 * (step(0.0, gy00) - 0.5);\n" \
	"\n" \
	"	vec4 gx01 = ixy01 * (1.0 / 7.0);\n" \
	"	vec4 gy01 = floor(gx01) * (1.0 / 7.0);\n" \
	"	vec4 gz01 = floor(gy01) * (1.0 / 6.0);\n" \
	"	gx01 = fract(gx01) - 0.5;\n" \
	"	gy01 = fract(gy01) - 0.5;\n" \
	"	gz01 = fract(gz01) - 0.5;\n" \
	"	vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01);\n" \
	"	vec4 sw01 = step(gw01, vec4(0.0));\n" \
	"	gx01 -= sw01 * (step(0.0, gx01) - 0.5);\n" \
	"	gy01 -= sw01 * (step(0.0, gy01) - 0.5);\n" \
	"\n" \
	"	vec4 gx10 = ixy10 * (1.0 / 7.0);\n" \
	"	vec4 gy10 = floor(gx10) * (1.0 / 7.0);\n" \
	"	vec4 gz10 = floor(gy10) * (1.0 / 6.0);\n" \
	"	gx10 = fract(gx10) - 0.5;\n" \
	"	gy10 = fract(gy10) - 0.5;\n" \
	"	gz10 = fract(gz10) - 0.5;\n" \
	"	vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10);\n" \
	"	vec4 sw10 = step(gw10, vec4(0.0));\n" \
	"	gx10 -= sw10 * (step(0.0, gx10) - 0.5);\n" \
	"	gy10 -= sw10 * (step(0.0, gy10) - 0.5);\n" \
	"\n" \
	"	vec4 gx11 = ixy11 * (1.0 / 7.0);\n" \
	"	vec4 gy11 = floor(gx11) * (1.0 / 7.0);\n" \
	"	vec4 gz11 = floor(gy11) * (1.0 / 6.0);\n" \
	"	gx11 = fract(gx11) - 0.5;\n" \
	"	gy11 = fract(gy11) - 0.5;\n" \
	"	gz11 = fract(gz11) - 0.5;\n" \
	"	vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11);\n" \
	"	vec4 sw11 = step(gw11, vec4(0.0));\n" \
	"	gx11 -= sw11 * (step(0.0, gx11) - 0.5);\n" \
	"	gy11 -= sw11 * (step(0.0, gy11) - 0.5);\n" \
	"\n" \
	"	vec4 g0000 = vec4(gx00.x, gy00.x, gz00.x, gw00.x);\n" \
	"	vec4 g1000 = vec4(gx00.y, gy00.y, gz00.y, gw00.y);\n" \
	"	vec4 g0100 = vec4(gx00.z, gy00.z, gz00.z, gw00.z);\n" \
	"	vec4 g1100 = vec4(gx00.w, gy00.w, gz00.w, gw00.w);\n" \
	"	vec4 g0010 = vec4(gx10.x, gy10.x, gz10.x, gw10.x);\n" \
	"	vec4 g1010 = vec4(gx10.y, gy10.y, gz10.y, gw10.y);\n" \
	"	vec4 g0110 = vec4(gx10.z, gy10.z, gz10.z, gw10.z);\n" \
	"	vec4 g1110 = vec4(gx10.w, gy10.w, gz10.w, gw10.w);\n" \
	"	vec4 g0001 = vec4(gx01.x, gy01.x, gz01.x, gw01.x);\n" \
	"	vec4 g1001 = vec4(gx01.y, gy01.y, gz01.y, gw01.y);\n" \
	"	vec4 g0101 = vec4(gx01.z, gy01.z, gz01.z, gw01.z);\n" \
	"	vec4 g1101 = vec4(gx01.w, gy01.w, gz01.w, gw01.w);\n" \
	"	vec4 g0011 = vec4(gx11.x, gy11.x, gz11.x, gw11.x);\n" \
	"	vec4 g1011 = vec4(gx11.y, gy11.y, gz11.y, gw11.y);\n" \
	"	vec4 g0111 = vec4(gx11.z, gy11.z, gz11.z, gw11.z);\n" \
	"	vec4 g1111 = vec4(gx11.w, gy11.w, gz11.w, gw11.w);\n" \
	"\n" \
	"	vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));\n" \
	"	g0000 *= norm00.x;\n" \
	"	g0100 *= norm00.y;\n" \
	"	g1000 *= norm00.z;\n" \
	"	g1100 *= norm00.w;\n" \
	"\n" \
	"	vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));\n" \
	"	g0001 *= norm01.x;\n" \
	"	g0101 *= norm01.y;\n" \
	"	g1001 *= norm01.z;\n" \
	"	g1101 *= norm01.w;\n" \
	"\n" \
	"	vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));\n" \
	"	g0010 *= norm10.x;\n" \
	"	g0110 *= norm10.y;\n" \
	"	g1010 *= norm10.z;\n" \
	"	g1110 *= norm10.w;\n" \
	"\n" \
	"	vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));\n" \
	"	g0011 *= norm11.x;\n" \
	"	g0111 *= norm11.y;\n" \
	"	g1011 *= norm11.z;\n" \
	"	g1111 *= norm11.w;\n" \
	"\n" \
	"	float n0000 = dot(g0000, Pf0);\n" \
	"	float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw));\n" \
	"	float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw));\n" \
	"	float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw));\n" \
	"	float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w));\n" \
	"	float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w));\n" \
	"	float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w));\n" \
	"	float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w));\n" \
	"	float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w));\n" \
	"	float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w));\n" \
	"	float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w));\n" \
	"	float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w));\n" \
	"	float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw));\n" \
	"	float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw));\n" \
	"	float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw));\n" \
	"	float n1111 = dot(g1111, Pf1);\n" \
	"\n" \
	"	vec4 fade_xyzw = fade(Pf0);\n" \
	"	vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w);\n" \
	"	vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w);\n" \
	"	vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z);\n" \
	"	vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y);\n" \
	"	float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);\n" \
	"	return 2.2 * n_xyzw;\n" \
	"}\n" \
	"\n" \
	"/**\n" \
	" *	@brief Classic Perlin noise, periodic version\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@param[in] rep is period\n" \
	" *\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float pnoise(vec4 P, vec4 rep)\n" \
	"{\n" \
	"	vec4 Pi0 = mod(floor(P), rep); // Integer part modulo rep\n" \
	"	vec4 Pi1 = mod(Pi0 + 1.0, rep); // Integer part + 1 mod rep\n" \
	"	Pi0 = mod289(Pi0);\n" \
	"	Pi1 = mod289(Pi1);\n" \
	"	vec4 Pf0 = fract(P); // Fractional part for interpolation\n" \
	"	vec4 Pf1 = Pf0 - 1.0; // Fractional part - 1.0\n" \
	"	vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);\n" \
	"	vec4 iy = vec4(Pi0.yy, Pi1.yy);\n" \
	"	vec4 iz0 = vec4(Pi0.zzzz);\n" \
	"	vec4 iz1 = vec4(Pi1.zzzz);\n" \
	"	vec4 iw0 = vec4(Pi0.wwww);\n" \
	"	vec4 iw1 = vec4(Pi1.wwww);\n" \
	"\n" \
	"	vec4 ixy = permute(permute(ix) + iy);\n" \
	"	vec4 ixy0 = permute(ixy + iz0);\n" \
	"	vec4 ixy1 = permute(ixy + iz1);\n" \
	"	vec4 ixy00 = permute(ixy0 + iw0);\n" \
	"	vec4 ixy01 = permute(ixy0 + iw1);\n" \
	"	vec4 ixy10 = permute(ixy1 + iw0);\n" \
	"	vec4 ixy11 = permute(ixy1 + iw1);\n" \
	"\n" \
	"	vec4 gx00 = ixy00 * (1.0 / 7.0);\n" \
	"	vec4 gy00 = floor(gx00) * (1.0 / 7.0);\n" \
	"	vec4 gz00 = floor(gy00) * (1.0 / 6.0);\n" \
	"	gx00 = fract(gx00) - 0.5;\n" \
	"	gy00 = fract(gy00) - 0.5;\n" \
	"	gz00 = fract(gz00) - 0.5;\n" \
	"	vec4 gw00 = vec4(0.75) - abs(gx00) - abs(gy00) - abs(gz00);\n" \
	"	vec4 sw00 = step(gw00, vec4(0.0));\n" \
	"	gx00 -= sw00 * (step(0.0, gx00) - 0.5);\n" \
	"	gy00 -= sw00 * (step(0.0, gy00) - 0.5);\n" \
	"\n" \
	"	vec4 gx01 = ixy01 * (1.0 / 7.0);\n" \
	"	vec4 gy01 = floor(gx01) * (1.0 / 7.0);\n" \
	"	vec4 gz01 = floor(gy01) * (1.0 / 6.0);\n" \
	"	gx01 = fract(gx01) - 0.5;\n" \
	"	gy01 = fract(gy01) - 0.5;\n" \
	"	gz01 = fract(gz01) - 0.5;\n" \
	"	vec4 gw01 = vec4(0.75) - abs(gx01) - abs(gy01) - abs(gz01);\n" \
	"	vec4 sw01 = step(gw01, vec4(0.0));\n" \
	"	gx01 -= sw01 * (step(0.0, gx01) - 0.5);\n" \
	"	gy01 -= sw01 * (step(0.0, gy01) - 0.5);\n" \
	"\n" \
	"	vec4 gx10 = ixy10 * (1.0 / 7.0);\n" \
	"	vec4 gy10 = floor(gx10) * (1.0 / 7.0);\n" \
	"	vec4 gz10 = floor(gy10) * (1.0 / 6.0);\n" \
	"	gx10 = fract(gx10) - 0.5;\n" \
	"	gy10 = fract(gy10) - 0.5;\n" \
	"	gz10 = fract(gz10) - 0.5;\n" \
	"	vec4 gw10 = vec4(0.75) - abs(gx10) - abs(gy10) - abs(gz10);\n" \
	"	vec4 sw10 = step(gw10, vec4(0.0));\n" \
	"	gx10 -= sw10 * (step(0.0, gx10) - 0.5);\n" \
	"	gy10 -= sw10 * (step(0.0, gy10) - 0.5);\n" \
	"\n" \
	"	vec4 gx11 = ixy11 * (1.0 / 7.0);\n" \
	"	vec4 gy11 = floor(gx11) * (1.0 / 7.0);\n" \
	"	vec4 gz11 = floor(gy11) * (1.0 / 6.0);\n" \
	"	gx11 = fract(gx11) - 0.5;\n" \
	"	gy11 = fract(gy11) - 0.5;\n" \
	"	gz11 = fract(gz11) - 0.5;\n" \
	"	vec4 gw11 = vec4(0.75) - abs(gx11) - abs(gy11) - abs(gz11);\n" \
	"	vec4 sw11 = step(gw11, vec4(0.0));\n" \
	"	gx11 -= sw11 * (step(0.0, gx11) - 0.5);\n" \
	"	gy11 -= sw11 * (step(0.0, gy11) - 0.5);\n" \
	"\n" \
	"	vec4 g0000 = vec4(gx00.x, gy00.x, gz00.x, gw00.x);\n" \
	"	vec4 g1000 = vec4(gx00.y, gy00.y, gz00.y, gw00.y);\n" \
	"	vec4 g0100 = vec4(gx00.z, gy00.z, gz00.z, gw00.z);\n" \
	"	vec4 g1100 = vec4(gx00.w, gy00.w, gz00.w, gw00.w);\n" \
	"	vec4 g0010 = vec4(gx10.x, gy10.x, gz10.x, gw10.x);\n" \
	"	vec4 g1010 = vec4(gx10.y, gy10.y, gz10.y, gw10.y);\n" \
	"	vec4 g0110 = vec4(gx10.z, gy10.z, gz10.z, gw10.z);\n" \
	"	vec4 g1110 = vec4(gx10.w, gy10.w, gz10.w, gw10.w);\n" \
	"	vec4 g0001 = vec4(gx01.x, gy01.x, gz01.x, gw01.x);\n" \
	"	vec4 g1001 = vec4(gx01.y, gy01.y, gz01.y, gw01.y);\n" \
	"	vec4 g0101 = vec4(gx01.z, gy01.z, gz01.z, gw01.z);\n" \
	"	vec4 g1101 = vec4(gx01.w, gy01.w, gz01.w, gw01.w);\n" \
	"	vec4 g0011 = vec4(gx11.x, gy11.x, gz11.x, gw11.x);\n" \
	"	vec4 g1011 = vec4(gx11.y, gy11.y, gz11.y, gw11.y);\n" \
	"	vec4 g0111 = vec4(gx11.z, gy11.z, gz11.z, gw11.z);\n" \
	"	vec4 g1111 = vec4(gx11.w, gy11.w, gz11.w, gw11.w);\n" \
	"\n" \
	"	vec4 norm00 = taylorInvSqrt(vec4(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));\n" \
	"	g0000 *= norm00.x;\n" \
	"	g0100 *= norm00.y;\n" \
	"	g1000 *= norm00.z;\n" \
	"	g1100 *= norm00.w;\n" \
	"\n" \
	"	vec4 norm01 = taylorInvSqrt(vec4(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));\n" \
	"	g0001 *= norm01.x;\n" \
	"	g0101 *= norm01.y;\n" \
	"	g1001 *= norm01.z;\n" \
	"	g1101 *= norm01.w;\n" \
	"\n" \
	"	vec4 norm10 = taylorInvSqrt(vec4(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));\n" \
	"	g0010 *= norm10.x;\n" \
	"	g0110 *= norm10.y;\n" \
	"	g1010 *= norm10.z;\n" \
	"	g1110 *= norm10.w;\n" \
	"\n" \
	"	vec4 norm11 = taylorInvSqrt(vec4(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));\n" \
	"	g0011 *= norm11.x;\n" \
	"	g0111 *= norm11.y;\n" \
	"	g1011 *= norm11.z;\n" \
	"	g1111 *= norm11.w;\n" \
	"\n" \
	"	float n0000 = dot(g0000, Pf0);\n" \
	"	float n1000 = dot(g1000, vec4(Pf1.x, Pf0.yzw));\n" \
	"	float n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.zw));\n" \
	"	float n1100 = dot(g1100, vec4(Pf1.xy, Pf0.zw));\n" \
	"	float n0010 = dot(g0010, vec4(Pf0.xy, Pf1.z, Pf0.w));\n" \
	"	float n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w));\n" \
	"	float n0110 = dot(g0110, vec4(Pf0.x, Pf1.yz, Pf0.w));\n" \
	"	float n1110 = dot(g1110, vec4(Pf1.xyz, Pf0.w));\n" \
	"	float n0001 = dot(g0001, vec4(Pf0.xyz, Pf1.w));\n" \
	"	float n1001 = dot(g1001, vec4(Pf1.x, Pf0.yz, Pf1.w));\n" \
	"	float n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w));\n" \
	"	float n1101 = dot(g1101, vec4(Pf1.xy, Pf0.z, Pf1.w));\n" \
	"	float n0011 = dot(g0011, vec4(Pf0.xy, Pf1.zw));\n" \
	"	float n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.zw));\n" \
	"	float n0111 = dot(g0111, vec4(Pf0.x, Pf1.yzw));\n" \
	"	float n1111 = dot(g1111, Pf1);\n" \
	"\n" \
	"	vec4 fade_xyzw = fade(Pf0);\n" \
	"	vec4 n_0w = mix(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w);\n" \
	"	vec4 n_1w = mix(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w);\n" \
	"	vec4 n_zw = mix(n_0w, n_1w, fade_xyzw.z);\n" \
	"	vec2 n_yzw = mix(n_zw.xy, n_zw.zw, fade_xyzw.y);\n" \
	"	float n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);\n" \
	"	return 2.2 * n_xyzw;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_CLASSIC_4D\n" \
	"\n"

/**
 *	@def GL_SIMPLEX_NOISE_2D_SRC
 *	@brief simplex 2D Perlin noise snoise()
 */
#define GL_SIMPLEX_NOISE_2D_SRC \
	"//\n" \
	"// Description : Array and textureless GLSL 2D simplex noise function.\n" \
	"//		Author : Ian McEwan, Ashima Arts.\n" \
	"//	Maintainer : ijm\n" \
	"//	   Lastmod : 20110822 (ijm)\n" \
	"//	   License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n" \
	"//				 Distributed under the MIT License. See LICENSE file.\n" \
	"//				 https://github.com/ashima/webgl-noise\n" \
	"//\n" \
	"\n" \
	"#ifndef __PNOISE_SIMPLEX_2D\n" \
	"#define __PNOISE_SIMPLEX_2D\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC3\n" \
	"#define __PNOISE_MOD289_VEC3\n" \
	"\n" \
	"vec3 mod289(vec3 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC3\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC2\n" \
	"#define __PNOISE_MOD289_VEC2\n" \
	"\n" \
	"vec2 mod289(vec2 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC2\n" \
	"\n" \
	"#ifndef __PNOISE_PERMUTE_VEC3\n" \
	"#define __PNOISE_PERMUTE_VEC3\n" \
	"\n" \
	"vec3 permute(vec3 x)\n" \
	"{\n" \
	"	return mod289(((x * 34.0) + 1.0) * x);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_PERMUTE_VEC3\n" \
	"\n" \
	"/**\n" \
	" *	@brief simplex Perlin noise\n" \
	" *	@param[in] v is the coordinate in noise domain\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float snoise(vec2 v)\n" \
	"{\n" \
	"	const vec4 C = vec4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0\n" \
	"		0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)\n" \
	"		-0.577350269189626, // -1.0 + 2.0 * C.x\n" \
	"		0.024390243902439); // 1.0 / 41.0\n" \
	"	// First corner\n" \
	"	vec2 i = floor(v + dot(v, C.yy));\n" \
	"	vec2 x0 = v - i + dot(i, C.xx);\n" \
	"\n" \
	"	// Other corners\n" \
	"	vec2 i1;\n" \
	"	// i1.x = step(x0.y, x0.x); // x0.x > x0.y ? 1.0 : 0.0\n" \
	"	// i1.y = 1.0 - i1.x;\n" \
	"	i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n" \
	"	// x0 = x0 - 0.0 + 0.0 * C.xx;\n" \
	"	// x1 = x0 - i1 + 1.0 * C.xx;\n" \
	"	// x2 = x0 - 1.0 + 2.0 * C.xx;\n" \
	"	vec4 x12 = x0.xyxy + C.xxzz;\n" \
	"	x12.xy -= i1;\n" \
	"\n" \
	"	// Permutations\n" \
	"	i = mod289(i); // Avoid truncation effects in permutation\n" \
	"	vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));\n" \
	"\n" \
	"	vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);\n" \
	"	m = m * m;\n" \
	"	m = m * m;\n" \
	"\n" \
	"	// Gradients: 41 points uniformly over a line, mapped onto a diamond.\n" \
	"	// The ring size 17 * 17 = 289 is close to a multiple of 41 (41 * 7 = 287)\n" \
	"\n" \
	"	vec3 x = 2.0 * fract(p * C.www) - 1.0;\n" \
	"	vec3 h = abs(x) - 0.5;\n" \
	"	vec3 ox = floor(x + 0.5);\n" \
	"	vec3 a0 = x - ox;\n" \
	"\n" \
	"	// Normalise gradients implicitly by scaling m\n" \
	"	// Approximation of: m *= inversesqrt(a0 * a0 + h * h);\n" \
	"	m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);\n" \
	"\n" \
	"	// Compute final noise value at P\n" \
	"	vec3 g;\n" \
	"	g.x = a0.x * x0.x + h.x * x0.y;\n" \
	"	g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n" \
	"	return 130.0 * dot(m, g);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_SIMPLEX_2D\n" \
	"\n"

/**
 *	@def GL_SIMPLEX_NOISE_3D_SRC
 *	@brief simplex 3D Perlin noise snoise()
 */
#define GL_SIMPLEX_NOISE_3D_SRC \
	"//\n" \
	"// Description : Array and textureless GLSL 2D/3D/4D simplex noise functions.\n" \
	"//		Author : Ian McEwan, Ashima Arts.\n" \
	"//	Maintainer : ijm\n" \
	"//	   Lastmod : 20110822 (ijm)\n" \
	"//	   License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n" \
	"//				 Distributed under the MIT License. See LICENSE file.\n" \
	"//				 https://github.com/ashima/webgl-noise\n" \
	"//\n" \
	"\n" \
	"#ifndef __PNOISE_SIMPLEX_3D\n" \
	"#define __PNOISE_SIMPLEX_3D\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC3\n" \
	"#define __PNOISE_MOD289_VEC3\n" \
	"\n" \
	"vec3 mod289(vec3 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC3\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC4\n" \
	"#define __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"vec4 mod289(vec4 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_PERMUTE_VEC4\n" \
	"#define __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"vec4 permute(vec4 x)\n" \
	"{\n" \
	"	return mod289(((x * 34.0) + 1.0) * x);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_RSQRT_VEC4\n" \
	"#define __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"vec4 taylorInvSqrt(vec4 r)\n" \
	"{\n" \
	"	return 1.79284291400159 - 0.85373472095314 * r;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"/**\n" \
	" *	@brief simplex Perlin noise\n" \
	" *	@param[in] v is the coordinate in noise domain\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float snoise(vec3 v)\n" \
	"{\n" \
	"	const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);\n" \
	"	const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n" \
	"\n" \
	"	// First corner\n" \
	"	vec3 i = floor(v + dot(v, C.yyy));\n" \
	"	vec3 x0 = v - i + dot(i, C.xxx);\n" \
	"\n" \
	"	// Other corners\n" \
	"	vec3 g = step(x0.yzx, x0.xyz);\n" \
	"	vec3 l = 1.0 - g;\n" \
	"	vec3 i1 = min(g.xyz, l.zxy);\n" \
	"	vec3 i2 = max(g.xyz, l.zxy);\n" \
	"\n" \
	"	// x0 = x0 - 0.0 + 0.0 * C.xxx;\n" \
	"	// x1 = x0 - i1 + 1.0 * C.xxx;\n" \
	"	// x2 = x0 - i2 + 2.0 * C.xxx;\n" \
	"	// x3 = x0 - 1.0 + 3.0 * C.xxx;\n" \
	"	vec3 x1 = x0 - i1 + C.xxx;\n" \
	"	vec3 x2 = x0 - i2 + C.yyy; // 2.0 * C.x = 1 / 3 = C.y\n" \
	"	vec3 x3 = x0 - D.yyy; // -1.0 + 3.0 * C.x = -0.5 = -D.y\n" \
	"\n" \
	"	// Permutations\n" \
	"	i = mod289(i);\n" \
	"	vec4 p = permute(permute(permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) +\n" \
	"		i.y + vec4(0.0, i1.y, i2.y, 1.0)) + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n" \
	"\n" \
	"	// Gradients: 7 x 7 points over a square, mapped onto an octahedron.\n" \
	"	// The ring size 17 * 17 = 289 is close to a multiple of 49 (49 * 6 = 294)\n" \
	"	float n_ = 0.142857142857; // 1.0 / 7.0\n" \
	"	vec3 ns = n_ * D.wyz - D.xzx;\n" \
	"\n" \
	"	vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p, 7 * 7)\n" \
	"\n" \
	"	vec4 x_ = floor(j * ns.z);\n" \
	"	vec4 y_ = floor(j - 7.0 * x_); // mod(j, N)\n" \
	"\n" \
	"	vec4 x = x_ * ns.x + ns.yyyy;\n" \
	"	vec4 y = y_ * ns.x + ns.yyyy;\n" \
	"	vec4 h = 1.0 - abs(x) - abs(y);\n" \
	"\n" \
	"	vec4 b0 = vec4(x.xy, y.xy);\n" \
	"	vec4 b1 = vec4(x.zw, y.zw);\n" \
	"\n" \
	"	//vec4 s0 = vec4(lessThan(b0, 0.0)) * 2.0 - 1.0;\n" \
	"	//vec4 s1 = vec4(lessThan(b1, 0.0)) * 2.0 - 1.0;\n" \
	"	vec4 s0 = floor(b0) * 2.0 + 1.0;\n" \
	"	vec4 s1 = floor(b1) * 2.0 + 1.0;\n" \
	"	vec4 sh = -step(h, vec4(0.0));\n" \
	"\n" \
	"	vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;\n" \
	"	vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;\n" \
	"\n" \
	"	vec3 p0 = vec3(a0.xy, h.x);\n" \
	"	vec3 p1 = vec3(a0.zw, h.y);\n" \
	"	vec3 p2 = vec3(a1.xy, h.z);\n" \
	"	vec3 p3 = vec3(a1.zw, h.w);\n" \
	"\n" \
	"	//Normalise gradients\n" \
	"	vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));\n" \
	"	p0 *= norm.x;\n" \
	"	p1 *= norm.y;\n" \
	"	p2 *= norm.z;\n" \
	"	p3 *= norm.w;\n" \
	"\n" \
	"	// Mix final noise value\n" \
	"	vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);\n" \
	"	m = m * m;\n" \
	"	return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_SIMPLEX_3D\n" \
	"\n"

/**
 *	@def GL_SIMPLEX_NOISE_4D_SRC
 *	@brief simplex 4D Perlin noise snoise()
 */
#define GL_SIMPLEX_NOISE_4D_SRC \
	"//\n" \
	"// Description : Array and textureless GLSL 2D/3D/4D simplex noise functions.\n" \
	"//		Author : Ian McEwan, Ashima Arts.\n" \
	"//	Maintainer : ijm\n" \
	"//	   Lastmod : 20110822 (ijm)\n" \
	"//	   License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n" \
	"//				 Distributed under the MIT License. See LICENSE file.\n" \
	"//				 https://github.com/ashima/webgl-noise\n" \
	"//\n" \
	"\n" \
	"#ifndef __PNOISE_SIMPLEX_4D\n" \
	"#define __PNOISE_SIMPLEX_4D\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_VEC4\n" \
	"#define __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"vec4 mod289(vec4 x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_MOD289_SCALAR\n" \
	"#define __PNOISE_MOD289_SCALAR\n" \
	"\n" \
	"float mod289(float x)\n" \
	"{\n" \
	"	return x - floor(x * (1.0 / 289.0)) * 289.0;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_MOD289_SCALAR\n" \
	"\n" \
	"#ifndef __PNOISE_PERMUTE_VEC4\n" \
	"#define __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"vec4 permute(vec4 x)\n" \
	"{\n" \
	"	return mod289(((x * 34.0) + 1.0) * x);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_PERMUTE_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_PERMUTE_SCALAR\n" \
	"#define __PNOISE_PERMUTE_SCALAR\n" \
	"\n" \
	"float permute(float x)\n" \
	"{\n" \
	"	return mod289(((x * 34.0) + 1.0) * x);\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_PERMUTE_SCALAR\n" \
	"\n" \
	"#ifndef __PNOISE_RSQRT_VEC4\n" \
	"#define __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"vec4 taylorInvSqrt(vec4 r)\n" \
	"{\n" \
	"	return 1.79284291400159 - 0.85373472095314 * r;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_RSQRT_VEC4\n" \
	"\n" \
	"#ifndef __PNOISE_RSQRT_SCALAR\n" \
	"#define __PNOISE_RSQRT_SCALAR\n" \
	"\n" \
	"float taylorInvSqrt(float r)\n" \
	"{\n" \
	"	return 1.79284291400159 - 0.85373472095314 * r;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_RSQRT_SCALAR\n" \
	"\n" \
	"#ifndef __PNOISE_GRAD_VEC4\n" \
	"#define __PNOISE_GRAD_VEC4\n" \
	"\n" \
	"vec4 grad4(float j, vec4 ip)\n" \
	"{\n" \
	"	const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);\n" \
	"	vec4 p, s;\n" \
	"\n" \
	"	p.xyz = floor(fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;\n" \
	"	p.w = 1.5 - dot(abs(p.xyz), ones.xyz);\n" \
	"	s = vec4(lessThan(p, vec4(0.0)));\n" \
	"	p.xyz = p.xyz + (s.xyz * 2.0 - 1.0) * s.www;\n" \
	"\n" \
	"	return p;\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_GRAD_VEC4\n" \
	"\n" \
	"// (sqrt(5) - 1)/4 = F4, used once below\n" \
	"//#define F4 0.309016994374947451\n" \
	"\n" \
	"/**\n" \
	" *	@brief simplex Perlin noise\n" \
	" *	@param[in] v is the coordinate in noise domain\n" \
	" *	@return Returns noise.\n" \
	" */\n" \
	"float snoise(vec4 v)\n" \
	"{\n" \
	"	const vec4 C = vec4(0.138196601125011, // (5 - sqrt(5)) / 20 * G4\n" \
	"		0.276393202250021, // 2 * G4\n" \
	"		0.414589803375032, // 3 * G4\n" \
	"		-0.447213595499958); // -1 + 4 * G4\n" \
	"\n" \
	"	// First corner\n" \
	"	vec4 i = floor(v + dot(v, vec4(/*F4*/0.309016994374947451)));\n" \
	"	vec4 x0 = v - i + dot(i, C.xxxx);\n" \
	"\n" \
	"	// Other corners\n" \
	"\n" \
	"	// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)\n" \
	"	vec4 i0;\n" \
	"	vec3 isX = step(x0.yzw, x0.xxx);\n" \
	"	vec3 isYZ = step(x0.zww, x0.yyz);\n" \
	"	// i0.x = dot(isX, vec3(1.0));\n" \
	"	i0.x = isX.x + isX.y + isX.z;\n" \
	"	i0.yzw = 1.0 - isX;\n" \
	"	// i0.y += dot(isYZ.xy, vec2(1.0));\n" \
	"	i0.y += isYZ.x + isYZ.y;\n" \
	"	i0.zw += 1.0 - isYZ.xy;\n" \
	"	i0.z += isYZ.z;\n" \
	"	i0.w += 1.0 - isYZ.z;\n" \
	"\n" \
	"	// i0 now contains the unique values 0, 1, 2, 3 in each channel\n" \
	"	vec4 i3 = clamp(i0, 0.0, 1.0);\n" \
	"	vec4 i2 = clamp(i0 - 1.0, 0.0, 1.0);\n" \
	"	vec4 i1 = clamp(i0 - 2.0, 0.0, 1.0);\n" \
	"\n" \
	"	// x0 = x0 - 0.0 + 0.0 * C.xxxx\n" \
	"	// x1 = x0 - i1 + 1.0 * C.xxxx\n" \
	"	// x2 = x0 - i2 + 2.0 * C.xxxx\n" \
	"	// x3 = x0 - i3 + 3.0 * C.xxxx\n" \
	"	// x4 = x0 - 1.0 + 4.0 * C.xxxx\n" \
	"	vec4 x1 = x0 - i1 + C.xxxx;\n" \
	"	vec4 x2 = x0 - i2 + C.yyyy;\n" \
	"	vec4 x3 = x0 - i3 + C.zzzz;\n" \
	"	vec4 x4 = x0 + C.wwww;\n" \
	"\n" \
	"	// Permutations\n" \
	"	i = mod289(i);\n" \
	"	float j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x);\n" \
	"	vec4 j1 = permute(permute(permute(permute(i.w + vec4(i1.w, i2.w, i3.w, 1.0)) +\n" \
	"		i.z + vec4(i1.z, i2.z, i3.z, 1.0)) + i.y + vec4(i1.y, i2.y, i3.y, 1.0)) +\n" \
	"		i.x + vec4(i1.x, i2.x, i3.x, 1.0));\n" \
	"\n" \
	"	// Gradients: 7 x 7 x 6 points over a cube, mapped onto a 4-cross polytope\n" \
	"	// 7 * 7 * 6 = 294, which is close to the ring size 17 * 17 = 289.\n" \
	"	vec4 ip = vec4(1.0 / 294.0, 1.0 / 49.0, 1.0 / 7.0, 0.0);\n" \
	"\n" \
	"	vec4 p0 = grad4(j0, ip);\n" \
	"	vec4 p1 = grad4(j1.x, ip);\n" \
	"	vec4 p2 = grad4(j1.y, ip);\n" \
	"	vec4 p3 = grad4(j1.z, ip);\n" \
	"	vec4 p4 = grad4(j1.w, ip);\n" \
	"\n" \
	"	// Normalise gradients\n" \
	"	vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));\n" \
	"	p0 *= norm.x;\n" \
	"	p1 *= norm.y;\n" \
	"	p2 *= norm.z;\n" \
	"	p3 *= norm.w;\n" \
	"	p4 *= taylorInvSqrt(dot(p4, p4));\n" \
	"\n" \
	"	// Mix contributions from the five corners\n" \
	"	vec3 m0 = max(0.6 - vec3(dot(x0, x0), dot(x1, x1), dot(x2, x2)), 0.0);\n" \
	"	vec2 m1 = max(0.6 - vec2(dot(x3, x3), dot(x4, x4)), 0.0);\n" \
	"	m0 = m0 * m0;\n" \
	"	m1 = m1 * m1;\n" \
	"	return 49.0 * (dot(m0 * m0, vec3(dot(p0, x0), dot(p1, x1), dot(p2, x2))) +\n" \
	"		dot(m1 * m1, vec2(dot(p3, x3), dot(p4, x4))));\n" \
	"}\n" \
	"\n" \
	"#endif // __PNOISE_SIMPLEX_4D\n" \
	"\n"

/**
 *	@def GL_CELL_NOISE_2D_SRC
 *	@brief classic 2D Worley noise cellular()
 */
#define GL_CELL_NOISE_2D_SRC \
	"// Cellular noise (\"Worley noise\") in 2D in GLSL.\n" \
	"// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.\n" \
	"// This code is released under the conditions of the MIT license.\n" \
	"// See LICENSE file for details.\n" \
	"\n" \
	"#ifndef __CELL_NOISE_2D\n" \
	"#define __CELL_NOISE_2D\n" \
	"\n" \
	"#ifndef __CELL_NOISE_PERMUTE_VEC3\n" \
	"#define __CELL_NOISE_PERMUTE_VEC3\n" \
	"\n" \
	"vec3 cell_permute(vec3 x)\n" \
	"{\n" \
	"	return mod((34.0 * x + 1.0) * x, 289.0); // Permutation polynomial: (34x^2 + x) mod 289\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_PERMUTE_VEC3\n" \
	"\n" \
	"/**\n" \
	" *	@brief cellular noise function\n" \
	" *\n" \
	" *	Standard 3x3 search window for good F1 and F2 values.\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@return Returns F1 and F2 in a vec2\n" \
	" */\n" \
	"vec2 cellular(vec2 P)\n" \
	"{\n" \
	"	const float K = 0.142857142857; // 1/7\n" \
	"	const float Ko = 0.428571428571; // 3/7\n" \
	"	const float jitter = 1.0; // Less gives more regular pattern\n" \
	"	// hopefully these will be optimized away as constants\n" \
	"\n" \
	"	vec2 Pi = mod(floor(P), 289.0);\n" \
	"	vec2 Pf = fract(P);\n" \
	"	vec3 oi = vec3(-1.0, 0.0, 1.0);\n" \
	"	vec3 of = vec3(-0.5, 0.5, 1.5);\n" \
	"	vec3 px = cell_permute(Pi.x + oi);\n" \
	"	vec3 p = cell_permute(px.x + Pi.y + oi); // p11, p12, p13\n" \
	"	vec3 ox = fract(p * K) - Ko;\n" \
	"	vec3 oy = mod(floor(p * K),7.0) * K - Ko;\n" \
	"	vec3 dx = Pf.x + 0.5 + jitter * ox;\n" \
	"	vec3 dy = Pf.y - of + jitter * oy;\n" \
	"	vec3 d1 = dx * dx + dy * dy; // d11, d12 and d13, squared\n" \
	"	p = cell_permute(px.y + Pi.y + oi); // p21, p22, p23\n" \
	"	ox = fract(p * K) - Ko;\n" \
	"	oy = mod(floor(p * K),7.0) * K - Ko;\n" \
	"	dx = Pf.x - 0.5 + jitter * ox;\n" \
	"	dy = Pf.y - of + jitter * oy;\n" \
	"	vec3 d2 = dx * dx + dy * dy; // d21, d22 and d23, squared\n" \
	"\n" \
	"	p = cell_permute(px.z + Pi.y + oi); // p31, p32, p33\n" \
	"	ox = fract(p * K) - Ko;\n" \
	"	oy = mod(floor(p * K), 7.0) * K - Ko;\n" \
	"	dx = Pf.x - 1.5 + jitter * ox;\n" \
	"	dy = Pf.y - of + jitter * oy;\n" \
	"	vec3 d3 = dx * dx + dy * dy; // d31, d32 and d33, squared\n" \
	"	// Sort out the two smallest distances (F1, F2)\n" \
	"	vec3 d1a = min(d1, d2);\n" \
	"	d2 = max(d1, d2); // Swap to keep candidates for F2\n" \
	"	d2 = min(d2, d3); // neither F1 nor F2 are now in d3\n" \
	"	d1 = min(d1a, d2); // F1 is now in d1\n" \
	"\n" \
	"	d2 = max(d1a, d2); // Swap to keep candidates for F2\n" \
	"	d1.xy = (d1.x < d1.y)? d1.xy : d1.yx; // Swap if smaller\n" \
	"	d1.xz = (d1.x < d1.z)? d1.xz : d1.zx; // F1 is in d1.x\n" \
	"	d1.yz = min(d1.yz, d2.yz); // F2 is now not in d2.yz\n" \
	"	d1.y = min(d1.y, d1.z); // nor in  d1.z\n" \
	"	d1.y = min(d1.y, d2.x); // F2 is in d1.y, we're done.\n" \
	"	return sqrt(d1.xy);\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_2D\n" \
	"\n"

/**
 *	@def GL_CELL_NOISE_2D_FAST_SRC
 *	@brief fast 2D Worley noise cellular2x2()
 */
#define GL_CELL_NOISE_2D_FAST_SRC \
	"// Cellular noise (\"Worley noise\") in 2D in GLSL.\n" \
	"// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.\n" \
	"// This code is released under the conditions of the MIT license.\n" \
	"// See LICENSE file for details.\n" \
	"\n" \
	"#ifndef __CELL_NOISE_2D_FAST\n" \
	"#define __CELL_NOISE_2D_FAST\n" \
	"\n" \
	"#ifndef __CELL_NOISE_PERMUTE_VEC4\n" \
	"#define __CELL_NOISE_PERMUTE_VEC4\n" \
	"\n" \
	"vec4 cell_permute(vec4 x)\n" \
	"{\n" \
	"	return mod((34.0 * x + 1.0) * x, 289.0); // Permutation polynomial: (34x^2 + x) mod 289\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_PERMUTE_VEC4\n" \
	"\n" \
	"/**\n" \
	" *	@brief fast approximate cellular noise function\n" \
	" *\n" \
	" *	Speeded up by using 2x2 search window instead of 3x3\n" \
	" *	at the expense of some strong pattern artifacts.\n" \
	" *	F2 is often wrong and has sharp discontinuities.\n" \
	" *	If you need a good F2, use the slower 3x3x3 version\n" \
	" *	F1 is sometimes wrong, too, but OK for most purposes.\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@return Returns F1 and F2 in a vec2\n" \
	" */\n" \
	"vec2 cellular2x2(vec2 P)\n" \
	"{\n" \
	"	const float K = 0.142857142857; // 1/7\n" \
	"	const float K2 = 0.0714285714285; // K/2\n" \
	"	const float jitter = 0.8; // jitter 1.0 makes F1 wrong more often\n" \
	"	// hopefully these will be optimized away as constants\n" \
	"\n" \
	"	vec2 Pi = mod(floor(P), 289.0);\n" \
	"	vec2 Pf = fract(P);\n" \
	"	vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5);\n" \
	"	vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5);\n" \
	"	vec4 p = cell_permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0));\n" \
	"	p = cell_permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0));\n" \
	"	vec4 ox = mod(p, 7.0)*K+K2;\n" \
	"	vec4 oy = mod(floor(p*K),7.0)*K+K2;\n" \
	"	vec4 dx = Pfx + jitter*ox;\n" \
	"	vec4 dy = Pfy + jitter*oy;\n" \
	"	vec4 d = dx * dx + dy * dy; // d11, d12, d21 and d22, squared\n" \
	"	// Sort out the two smallest distances\n" \
	"#if 0\n" \
	"	// Cheat and pick only F1\n" \
	"	d.xy = min(d.xy, d.zw);\n" \
	"	d.x = min(d.x, d.y);\n" \
	"	return d.xx; // F1 duplicated, F2 not computed\n" \
	"#else\n" \
	"\n" \
	"	// Do it right and find both F1 and F2\n" \
	"	d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap if smaller\n" \
	"	d.xz = (d.x < d.z) ? d.xz : d.zx;\n" \
	"	d.xw = (d.x < d.w) ? d.xw : d.wx;\n" \
	"	d.y = min(d.y, d.z);\n" \
	"	d.y = min(d.y, d.w);\n" \
	"	return sqrt(d.xy);\n" \
	"#endif\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_2D_FAST\n" \
	"\n"

/**
 *	@def GL_CELL_NOISE_3D_SRC
 *	@brief classic 3D Worley noise cellular()
 */
#define GL_CELL_NOISE_3D_SRC \
	"// Cellular noise (\"Worley noise\") in 3D in GLSL.\n" \
	"// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.\n" \
	"// This code is released under the conditions of the MIT license.\n" \
	"// See LICENSE file for details.\n" \
	"\n" \
	"#ifndef __CELL_NOISE_3D\n" \
	"#define __CELL_NOISE_3D\n" \
	"\n" \
	"#ifndef __CELL_NOISE_PERMUTE_VEC3\n" \
	"#define __CELL_NOISE_PERMUTE_VEC3\n" \
	"\n" \
	"vec3 cell_permute(vec3 x)\n" \
	"\n" \
	"{\n" \
	"	return mod((34.0 * x + 1.0) * x, 289.0); // Permutation polynomial: (34x^2 + x) mod 289\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_PERMUTE_VEC3\n" \
	"\n" \
	"/**\n" \
	" *	@brief cellular noise function\n" \
	" *\n" \
	" *	3x3x3 search region for good F2 everywhere, but a lot\n" \
	" *	slower than the 2x2x2 version.\n" \
	" *	The code below is a bit scary even to its author,\n" \
	" *	but it has at least half decent performance on a\n" \
	" *	modern GPU. In any case, it beats any software\n" \
	" *	implementation of Worley noise hands down.\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@return Returns F1 and F2 in a vec2\n" \
	" */\n" \
	"vec2 cellular(vec3 P)\n" \
	"{\n" \
	"	const float K = 0.142857142857; // 1/7\n" \
	"	const float Ko = 0.428571428571; // 1/2-K/2\n" \
	"	const float K2 = 0.020408163265306; // 1/(7*7)\n" \
	"	const float Kz = 0.166666666667; // 1/6\n" \
	"	const float Kzo = 0.416666666667; // 1/2-1/6*2\n" \
	"	const float jitter = 1.0; // smaller jitter gives more regular pattern\n" \
	"	// hopefully these will be optimized away as constants\n" \
	"\n" \
	"	vec3 Pi = mod(floor(P), 289.0);\n" \
	"	vec3 Pf = fract(P) - 0.5;\n" \
	"\n" \
	"	vec3 Pfx = Pf.x + vec3(1.0, 0.0, -1.0);\n" \
	"	vec3 Pfy = Pf.y + vec3(1.0, 0.0, -1.0);\n" \
	"	vec3 Pfz = Pf.z + vec3(1.0, 0.0, -1.0);\n" \
	"\n" \
	"	vec3 p = cell_permute(Pi.x + vec3(-1.0, 0.0, 1.0));\n" \
	"	vec3 p1 = cell_permute(p + Pi.y - 1.0);\n" \
	"	vec3 p2 = cell_permute(p + Pi.y);\n" \
	"	vec3 p3 = cell_permute(p + Pi.y + 1.0);\n" \
	"\n" \
	"	vec3 p11 = cell_permute(p1 + Pi.z - 1.0);\n" \
	"	vec3 p12 = cell_permute(p1 + Pi.z);\n" \
	"	vec3 p13 = cell_permute(p1 + Pi.z + 1.0);\n" \
	"\n" \
	"	vec3 p21 = cell_permute(p2 + Pi.z - 1.0);\n" \
	"	vec3 p22 = cell_permute(p2 + Pi.z);\n" \
	"	vec3 p23 = cell_permute(p2 + Pi.z + 1.0);\n" \
	"\n" \
	"	vec3 p31 = cell_permute(p3 + Pi.z - 1.0);\n" \
	"	vec3 p32 = cell_permute(p3 + Pi.z);\n" \
	"	vec3 p33 = cell_permute(p3 + Pi.z + 1.0);\n" \
	"\n" \
	"	vec3 ox11 = fract(p11*K) - Ko;\n" \
	"	vec3 oy11 = mod(floor(p11*K), 7.0)*K - Ko;\n" \
	"	vec3 oz11 = floor(p11*K2)*Kz - Kzo; // p11 < 289 guaranteed\n" \
	"\n" \
	"	vec3 ox12 = fract(p12*K) - Ko;\n" \
	"	vec3 oy12 = mod(floor(p12*K), 7.0)*K - Ko;\n" \
	"	vec3 oz12 = floor(p12*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 ox13 = fract(p13*K) - Ko;\n" \
	"	vec3 oy13 = mod(floor(p13*K), 7.0)*K - Ko;\n" \
	"	vec3 oz13 = floor(p13*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 ox21 = fract(p21*K) - Ko;\n" \
	"	vec3 oy21 = mod(floor(p21*K), 7.0)*K - Ko;\n" \
	"	vec3 oz21 = floor(p21*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 ox22 = fract(p22*K) - Ko;\n" \
	"	vec3 oy22 = mod(floor(p22*K), 7.0)*K - Ko;\n" \
	"	vec3 oz22 = floor(p22*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 ox23 = fract(p23*K) - Ko;\n" \
	"	vec3 oy23 = mod(floor(p23*K), 7.0)*K - Ko;\n" \
	"	vec3 oz23 = floor(p23*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 ox31 = fract(p31*K) - Ko;\n" \
	"	vec3 oy31 = mod(floor(p31*K), 7.0)*K - Ko;\n" \
	"	vec3 oz31 = floor(p31*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 ox32 = fract(p32*K) - Ko;\n" \
	"	vec3 oy32 = mod(floor(p32*K), 7.0)*K - Ko;\n" \
	"	vec3 oz32 = floor(p32*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 ox33 = fract(p33*K) - Ko;\n" \
	"	vec3 oy33 = mod(floor(p33*K), 7.0)*K - Ko;\n" \
	"	vec3 oz33 = floor(p33*K2)*Kz - Kzo;\n" \
	"\n" \
	"	vec3 dx11 = Pfx + jitter*ox11;\n" \
	"	vec3 dy11 = Pfy.x + jitter*oy11;\n" \
	"	vec3 dz11 = Pfz.x + jitter*oz11;\n" \
	"\n" \
	"	vec3 dx12 = Pfx + jitter*ox12;\n" \
	"	vec3 dy12 = Pfy.x + jitter*oy12;\n" \
	"	vec3 dz12 = Pfz.y + jitter*oz12;\n" \
	"\n" \
	"	vec3 dx13 = Pfx + jitter*ox13;\n" \
	"	vec3 dy13 = Pfy.x + jitter*oy13;\n" \
	"	vec3 dz13 = Pfz.z + jitter*oz13;\n" \
	"\n" \
	"	vec3 dx21 = Pfx + jitter*ox21;\n" \
	"	vec3 dy21 = Pfy.y + jitter*oy21;\n" \
	"	vec3 dz21 = Pfz.x + jitter*oz21;\n" \
	"\n" \
	"	vec3 dx22 = Pfx + jitter*ox22;\n" \
	"	vec3 dy22 = Pfy.y + jitter*oy22;\n" \
	"	vec3 dz22 = Pfz.y + jitter*oz22;\n" \
	"\n" \
	"	vec3 dx23 = Pfx + jitter*ox23;\n" \
	"	vec3 dy23 = Pfy.y + jitter*oy23;\n" \
	"	vec3 dz23 = Pfz.z + jitter*oz23;\n" \
	"\n" \
	"	vec3 dx31 = Pfx + jitter*ox31;\n" \
	"	vec3 dy31 = Pfy.z + jitter*oy31;\n" \
	"	vec3 dz31 = Pfz.x + jitter*oz31;\n" \
	"\n" \
	"	vec3 dx32 = Pfx + jitter*ox32;\n" \
	"	vec3 dy32 = Pfy.z + jitter*oy32;\n" \
	"	vec3 dz32 = Pfz.y + jitter*oz32;\n" \
	"\n" \
	"	vec3 dx33 = Pfx + jitter*ox33;\n" \
	"	vec3 dy33 = Pfy.z + jitter*oy33;\n" \
	"	vec3 dz33 = Pfz.z + jitter*oz33;\n" \
	"\n" \
	"	vec3 d11 = dx11 * dx11 + dy11 * dy11 + dz11 * dz11;\n" \
	"	vec3 d12 = dx12 * dx12 + dy12 * dy12 + dz12 * dz12;\n" \
	"	vec3 d13 = dx13 * dx13 + dy13 * dy13 + dz13 * dz13;\n" \
	"	vec3 d21 = dx21 * dx21 + dy21 * dy21 + dz21 * dz21;\n" \
	"	vec3 d22 = dx22 * dx22 + dy22 * dy22 + dz22 * dz22;\n" \
	"	vec3 d23 = dx23 * dx23 + dy23 * dy23 + dz23 * dz23;\n" \
	"	vec3 d31 = dx31 * dx31 + dy31 * dy31 + dz31 * dz31;\n" \
	"	vec3 d32 = dx32 * dx32 + dy32 * dy32 + dz32 * dz32;\n" \
	"	vec3 d33 = dx33 * dx33 + dy33 * dy33 + dz33 * dz33;\n" \
	"\n" \
	"	// Sort out the two smallest distances (F1, F2)\n" \
	"#if 0\n" \
	"	// Cheat and sort out only F1\n" \
	"\n" \
	"	vec3 d1 = min(min(d11,d12), d13);\n" \
	"	vec3 d2 = min(min(d21,d22), d23);\n" \
	"	vec3 d3 = min(min(d31,d32), d33);\n" \
	"	vec3 d = min(min(d1,d2), d3);\n" \
	"	d.x = min(min(d.x,d.y),d.z);\n" \
	"	return sqrt(d.xx); // F1 duplicated, no F2 computed\n" \
	"#else\n" \
	"	// Do it right and sort out both F1 and F2\n" \
	"	vec3 d1a = min(d11, d12);\n" \
	"	d12 = max(d11, d12);\n" \
	"	d11 = min(d1a, d13); // Smallest now not in d12 or d13\n" \
	"	d13 = max(d1a, d13);\n" \
	"	d12 = min(d12, d13); // 2nd smallest now not in d13\n" \
	"	vec3 d2a = min(d21, d22);\n" \
	"	d22 = max(d21, d22);\n" \
	"	d21 = min(d2a, d23); // Smallest now not in d22 or d23\n" \
	"	d23 = max(d2a, d23);\n" \
	"	d22 = min(d22, d23); // 2nd smallest now not in d23\n" \
	"	vec3 d3a = min(d31, d32);\n" \
	"	d32 = max(d31, d32);\n" \
	"	d31 = min(d3a, d33); // Smallest now not in d32 or d33\n" \
	"	d33 = max(d3a, d33);\n" \
	"	d32 = min(d32, d33); // 2nd smallest now not in d33\n" \
	"	vec3 da = min(d11, d21);\n" \
	"	d21 = max(d11, d21);\n" \
	"	d11 = min(da, d31); // Smallest now in d11\n" \
	"	d31 = max(da, d31); // 2nd smallest now not in d31\n" \
	"	d11.xy = (d11.x < d11.y) ? d11.xy : d11.yx;\n" \
	"	d11.xz = (d11.x < d11.z) ? d11.xz : d11.zx; // d11.x now smallest\n" \
	"	d12 = min(d12, d21); // 2nd smallest now not in d21\n" \
	"	d12 = min(d12, d22); // nor in d22\n" \
	"	d12 = min(d12, d31); // nor in d31\n" \
	"	d12 = min(d12, d32); // nor in d32\n" \
	"	d11.yz = min(d11.yz,d12.xy); // nor in d12.yz\n" \
	"	d11.y = min(d11.y,d12.z); // Only two more to go\n" \
	"	d11.y = min(d11.y,d11.z); // Done! (Phew!)\n" \
	"	return sqrt(d11.xy); // F1, F2\n" \
	"#endif\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_3D\n" \
	"\n"

/**
 *	@def GL_CELL_NOISE_3D_FAST_SRC
 *	@brief fast 3D Worley noise cellular()
 */
#define GL_CELL_NOISE_3D_FAST_SRC \
	"// Cellular noise (\"Worley noise\") in 3D in GLSL.\n" \
	"// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.\n" \
	"// This code is released under the conditions of the MIT license.\n" \
	"// See LICENSE file for details.\n" \
	"\n" \
	"#ifndef __CELL_NOISE_3D_FAST\n" \
	"#define __CELL_NOISE_3D_FAST\n" \
	"\n" \
	"#ifndef __CELL_NOISE_PERMUTE_VEC4\n" \
	"#define __CELL_NOISE_PERMUTE_VEC4\n" \
	"\n" \
	"vec4 cell_permute(vec4 x)\n" \
	"{\n" \
	"	return mod((34.0 * x + 1.0) * x, 289.0); // Permutation polynomial: (34x^2 + x) mod 289\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_PERMUTE_VEC4\n" \
	"\n" \
	"#ifndef __CELL_NOISE_PERMUTE_VEC3\n" \
	"#define __CELL_NOISE_PERMUTE_VEC3\n" \
	"\n" \
	"vec3 cell_permute(vec3 x)\n" \
	"{\n" \
	"	return mod((34.0 * x + 1.0) * x, 289.0); // Permutation polynomial: (34x^2 + x) mod 289\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_PERMUTE_VEC3\n" \
	"\n" \
	"/**\n" \
	" *	@brief fast approximate cellular noise function\n" \
	" *\n" \
	" *	Speeded up by using 2x2x2 search window instead of 3x3x3\n" \
	" *	at the expense of some pattern artifacts\n" \
	" *	F2 is often wrong and has sharp discontinuities\n" \
	" *	If you need a good F2, use the slower 3x3x3 version\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@return Returns F1 and F2 in a vec2\n" \
	" */\n" \
	"vec2 cellular2x2x2(vec3 P)\n" \
	"{\n" \
	"	const float K = 0.142857142857; // 1/7\n" \
	"	const float Ko = 0.428571428571; // 1/2-K/2\n" \
	"	const float K2 = 0.020408163265306; // 1/(7*7)\n" \
	"	const float Kz = 0.166666666667; // 1/6\n" \
	"	const float Kzo = 0.416666666667; // 1/2-1/6*2\n" \
	"	const float jitter = 0.8; // smaller jitter gives less errors in F2\n" \
	"	// hopefully these will be optimized away as constants\n" \
	"\n" \
	"	vec3 Pi = mod(floor(P), 289.0);\n" \
	"	vec3 Pf = fract(P);\n" \
	"	vec4 Pfx = Pf.x + vec4(0.0, -1.0, 0.0, -1.0);\n" \
	"	vec4 Pfy = Pf.y + vec4(0.0, 0.0, -1.0, -1.0);\n" \
	"\n" \
	"	vec4 p = cell_permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0));\n" \
	"	p = cell_permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0));\n" \
	"	vec4 p1 = cell_permute(p + Pi.z); // z+0\n" \
	"	vec4 p2 = cell_permute(p + Pi.z + vec4(1.0)); // z+1\n" \
	"	vec4 ox1 = fract(p1*K) - Ko;\n" \
	"	vec4 oy1 = mod(floor(p1*K), 7.0)*K - Ko;\n" \
	"	vec4 oz1 = floor(p1*K2)*Kz - Kzo; // p1 < 289 guaranteed\n" \
	"	vec4 ox2 = fract(p2*K) - Ko;\n" \
	"	vec4 oy2 = mod(floor(p2*K), 7.0)*K - Ko;\n" \
	"	vec4 oz2 = floor(p2*K2)*Kz - Kzo;\n" \
	"	vec4 dx1 = Pfx + jitter*ox1;\n" \
	"	vec4 dy1 = Pfy + jitter*oy1;\n" \
	"	vec4 dz1 = Pf.z + jitter*oz1;\n" \
	"	vec4 dx2 = Pfx + jitter*ox2;\n" \
	"	vec4 dy2 = Pfy + jitter*oy2;\n" \
	"	vec4 dz2 = Pf.z - 1.0 + jitter*oz2;\n" \
	"	vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1; // z+0\n" \
	"	vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2; // z+1\n" \
	"\n" \
	"	// Sort out the two smallest distances (F1, F2)\n" \
	"#if 0\n" \
	"	// Cheat and sort out only F1\n" \
	"	d1 = min(d1, d2);\n" \
	"	d1.xy = min(d1.xy, d1.wz);\n" \
	"	d1.x = min(d1.x, d1.y);\n" \
	"	return sqrt(d1.xx);\n" \
	"#else\n" \
	"	// Do it right and sort out both F1 and F2\n" \
	"	vec4 d = min(d1,d2); // F1 is now in d\n" \
	"	d2 = max(d1,d2); // Make sure we keep all candidates for F2\n" \
	"	d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap smallest to d.x\n" \
	"	d.xz = (d.x < d.z) ? d.xz : d.zx;\n" \
	"	d.xw = (d.x < d.w) ? d.xw : d.wx; // F1 is now in d.x\n" \
	"	d.yzw = min(d.yzw, d2.yzw); // F2 now not in d2.yzw\n" \
	"\n" \
	"	d.y = min(d.y, d.z); // nor in d.z\n" \
	"	d.y = min(d.y, d.w); // nor in d.w\n" \
	"	d.y = min(d.y, d2.x); // F2 is now in d.y\n" \
	"	return sqrt(d.xy); // F1 and F2\n" \
	"#endif\n" \
	"}\n" \
	"\n" \
	"#endif // __CELL_NOISE_3D_FAST\n" \
	"\n"

/**
 *	@def GL_FLOW_NOISE_2D_SRC
 *	@brief fast 2D flow noise srdnoise()
 */
#define GL_FLOW_NOISE_2D_SRC \
	"//\n" \
	"// GLSL implementation of 2D \"flow noise\" as presented\n" \
	"// by Ken Perlin and Fabrice Neyret at Siggraph 2001.\n" \
	"// (2D simplex noise with analytic derivatives and\n" \
	"// in-plane rotation of generating gradients,\n" \
	"// in a fractal sum where higher frequencies are\n" \
	"// displaced (advected) by lower frequencies in the\n" \
	"// direction of their gradient. For details, please\n" \
	"// refer to the 2001 paper \"Flow Noise\" by Perlin and Neyret.)\n" \
	"//\n" \
	"// Author: Stefan Gustavson (stefan.gustavson@liu.se)\n" \
	"// Distributed under the terms of the MIT license.\n" \
	"// See LICENSE file for details.\n" \
	"//\n" \
	"\n" \
	"#ifndef __FLOW_NOISE_2D\n" \
	"#define __FLOW_NOISE_2D\n" \
	"\n" \
	"float flow_permute(float x)\n" \
	"{\n" \
	"	return mod((34.0 * x + 1.0) * x, 289.0); // Permutation polynomial\n" \
	"}\n" \
	"\n" \
	"// Gradient mapping with an extra rotation.\n" \
	"vec2 flow_grad2(vec2 p, float rot)\n" \
	"{\n" \
	"	const float K = 0.0243902439; // 1/41\n" \
	"	// hopefully these will be optimized away as constants\n" \
	"#if 1\n" \
	"	// Map from a line to a diamond such that a shift maps to a rotation.\n" \
	"	float u = permute(flow_permute(p.x) + p.y) * K + rot; // Rotate by shift\n" \
	"	u = 4.0 * fract(u) - 2.0;\n" \
	"	return vec2(abs(u) - 1.0, abs(abs(u + 1.0) - 2.0) - 1.0);\n" \
	"#else\n" \
	"	const float TWOPI = 6.28318530718;\n" \
	"	// For more isotropic gradients, sin/cos can be used instead.\n" \
	"	float u = flow_permute(flow_permute(p.x) + p.y) * K + rot; // Rotate by shift\n" \
	"	u = fract(u) * TWOPI;\n" \
	"	return vec2(cos(u), sin(u));\n" \
	"#endif\n" \
	"}\n" \
	"\n" \
	"/**\n" \
	" *	@brief 2D flow noise\n" \
	" *\n" \
	" *	@param[in] P is the coordinate in noise domain\n" \
	" *	@param[in] rot is the rotation of the wiggle functions\n" \
	" *\n" \
	" *	@return Returns noise value followed by 2D gradient in a vec3.\n" \
	" *\n" \
	" *	@note The gradient(s) can be used to perturb the subsequent octaves\n" \
	" *		to achieve the desired flow effect.\n" \
	" */\n" \
	"vec3 srdnoise(vec2 P, float rot)\n" \
	"{\n" \
	"	// Helper constants\n" \
	"	const float F2 = 0.366025403;\n" \
	"	const float G2 = 0.211324865;\n" \
	"	// hopefully these will be optimized away as constants\n" \
	"\n" \
	"	// Transform input point to the skewed simplex grid\n" \
	"	vec2 Ps = P + dot(P, vec2(F2));\n" \
	"\n" \
	"	// Round down to simplex origin\n" \
	"	vec2 Pi = floor(Ps);\n" \
	"\n" \
	"	// Transform simplex origin back to (x,y) system\n" \
	"	vec2 P0 = Pi - dot(Pi, vec2(G2));\n" \
	"\n" \
	"	// Find (x,y) offsets from simplex origin to first corner\n" \
	"	vec2 v0 = P - P0;\n" \
	"\n" \
	"	// Pick (+x, +y) or (+y, +x) increment sequence\n" \
	"	vec2 i1 = (v0.x > v0.y)? vec2(1.0, 0.0) : vec2 (0.0, 1.0);\n" \
	"\n" \
	"	// Determine the offsets for the other two corners\n" \
	"	vec2 v1 = v0 - i1 + G2;\n" \
	"	vec2 v2 = v0 - 1.0 + 2.0 * G2;\n" \
	"\n" \
	"	// Wrap coordinates at 289 to avoid float precision problems\n" \
	"	Pi = mod(Pi, 289.0);\n" \
	"\n" \
	"	// Calculate the circularly symmetric part of each noise wiggle\n" \
	"	vec3 t = max(0.5 - vec3(dot(v0,v0), dot(v1,v1), dot(v2,v2)), 0.0);\n" \
	"	vec3 t2 = t * t;\n" \
	"	vec3 t4 = t2 * t2;\n" \
	"\n" \
	"	// Calculate the gradients for the three corners\n" \
	"	vec2 g0 = flow_grad2(Pi, rot);\n" \
	"	vec2 g1 = flow_grad2(Pi + i1, rot);\n" \
	"	vec2 g2 = flow_grad2(Pi + 1.0, rot);\n" \
	"\n" \
	"	// Compute noise contributions from each corner\n" \
	"	vec3 gv = vec3(dot(g0,v0), dot(g1,v1), dot(g2,v2)); // ramp: g dot v\n" \
	"	vec3 n = t4 * gv;  // Circular kernel times linear ramp\n" \
	"\n" \
	"	// Compute partial derivatives in x and y\n" \
	"	vec3 temp = t2 * t * gv;\n" \
	"	vec3 gradx = temp * vec3(v0.x, v1.x, v2.x);\n" \
	"	vec3 grady = temp * vec3(v0.y, v1.y, v2.y);\n" \
	"	vec2 grad;\n" \
	"	grad.x = -8.0 * (gradx.x + gradx.y + gradx.z);\n" \
	"	grad.y = -8.0 * (grady.x + grady.y + grady.z);\n" \
	"	grad.x += dot(t4, vec3(g0.x, g1.x, g2.x));\n" \
	"	grad.y += dot(t4, vec3(g0.y, g1.y, g2.y));\n" \
	"	grad *= 40.0;\n" \
	"\n" \
	"	// Add contributions from the three corners and return\n" \
	"	return vec3(40.0 * (n.x + n.y + n.z), grad);\n" \
	"}\n" \
	"\n" \
	"#endif // __FLOW_NOISE_2D\n" \
	"\n"

/**
 *	@def GL_CLASSIC_NOISE_ALL_SRC
 *	@brief versions of classic Perlin noise cnoise() and its periodic
 *		variant pnoise() for all the dimensions
 */
#define GL_CLASSIC_NOISE_ALL_SRC \
	GL_CLASSIC_NOISE_2D_SRC \
	GL_CLASSIC_NOISE_3D_SRC \
	GL_CLASSIC_NOISE_4D_SRC \

/**
 *	@def GL_SIMPLEX_NOISE_ALL_SRC
 *	@brief versions of simplex Perlin noise snoise() for all the dimensions
 */
#define GL_SIMPLEX_NOISE_ALL_SRC \
	GL_SIMPLEX_NOISE_2D_SRC \
	GL_SIMPLEX_NOISE_3D_SRC \
	GL_SIMPLEX_NOISE_4D_SRC

/**
 *	@def GL_CELL_NOISE_ALL_SRC
 *	@brief classic and fast variants of cell noise for 2D and 3D
 */
#define GL_CELL_NOISE_ALL_SRC \
	GL_CELL_NOISE_2D_SRC \
	GL_CELL_NOISE_2D_FAST_SRC \
	GL_CELL_NOISE_3D_SRC \
	GL_CELL_NOISE_3D_FAST_SRC

/**
 *	@def GL_FLOW_NOISE_ALL_SRC
 *	@brief all (the only) versions of flow noise (currently 2D only)
 */
#define GL_FLOW_NOISE_ALL_SRC \
	GL_FLOW_NOISE_2D_SRC

/**
 *	@def GL_ALL_NOISE_ALL_SRC
 *	@brief versions of classic Perlin noise cnoise() and its periodic
 *		variant pnoise() and simplex Perlin noise snoise() for all the dimensions,
 *		along with classic and fast variants of cell noise for 2D and 3D
 */
#define GL_ALL_NOISE_ALL_SRC \
	GL_CLASSIC_NOISE_ALL_SRC \
	GL_SIMPLEX_NOISE_ALL_SRC \
	GL_CELL_NOISE_ALL_SRC \
	GL_FLOW_NOISE_ALL_SRC

#endif // !__GLSL_NOISE_SOURCE_INCLUDED
