/*
* Author: Stefan Gustavson ITN-LiTH (stegu at itn.liu.se) 2004-12-05
* You may use, modify and redistribute this code free of charge,
* provided that my name and this notice appears intact.
*
* Modified: Nicolai de Haan Brøgger (ndhb78 at gmail.com)
*/
uniform sampler2D noisePermTexture;
/*
* To create offsets of one texel and one half texel in the
* texture lookup, we need to know the texture image size.
*/
#define ONE 0.00390625 // change accordingly if you change the code to use another texture size (1 / 256)
#define ONEHALF 0.001953125 // change accordingly if you change the code to use another texture size (0.5 / 256)
/*
* The interpolation function. This could be a 1D texture lookup
* to get some more speed, but it's not the main part of the algorithm.
*/
float fade(float t) {
return t*t*t*(t*(t*6.0-15.0)+10.0); // Improved fade, yields C2-continuous noise
} // function
/*
* 2D simplex noise. Somewhat slower but much better looking than classic noise.
*/
float snoise(vec2 P) {
// Skew and unskew factors are a bit hairy for 2D, so define them as constants
#define F2 0.366025403784 // This is (sqrt(3.0) - 1.0) / 2.0
#define G2 0.211324865405 // This is (3.0 - sqrt(3.0)) / 6.0
// Skew the (x,y) space to determine which cell of 2 simplices we're in
float s = (P.x + P.y) * F2; // Hairy factor for 2D skewing
vec2 Pi = floor(P + s);
float t = (Pi.x + Pi.y) * G2; // Hairy factor for unskewing
vec2 P0 = Pi - t; // Unskew the cell origin back to (x,y) space
Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup
vec2 Pf0 = P - P0; // The x,y distances from the cell origin
// For the 2D case, the simplex shape is an equilateral triangle.
// Find out whether we are above or below the x=y diagonal to
// determine which of the two triangles we're in.
vec2 o1;
if(Pf0.x > Pf0.y)
o1 = vec2(1.0, 0.0); // +x, +y traversal order
else
o1 = vec2(0.0, 1.0); // +y, +x traversal order
// Noise contribution from simplex origin
vec2 grad0 = texture2D(noisePermTexture, Pi).rg * 4.0 - 1.0;
float t0 = 0.5 - dot(Pf0, Pf0);
float n0;
if (t0 < 0.0) {
n0 = 0.0;
} else {
t0 *= t0;
n0 = t0 * t0 * dot(grad0, Pf0);
} // if else
// Noise contribution from middle corner
vec2 Pf1 = Pf0 - o1 + G2;
vec2 grad1 = texture2D(noisePermTexture, Pi + o1*ONE).rg * 4.0 - 1.0;
float t1 = 0.5 - dot(Pf1, Pf1);
float n1;
if (t1 < 0.0) {
n1 = 0.0;
} else {
t1 *= t1;
n1 = t1 * t1 * dot(grad1, Pf1);
} // if else
// Noise contribution from last corner
vec2 Pf2 = Pf0 - vec2(1.0-2.0*G2);
vec2 grad2 = texture2D(noisePermTexture, Pi + vec2(ONE, ONE)).rg * 4.0 - 1.0;
float t2 = 0.5 - dot(Pf2, Pf2);
float n2;
if(t2 < 0.0) {
n2 = 0.0;
} else {
t2 *= t2;
n2 = t2 * t2 * dot(grad2, Pf2);
} // if else
// Sum up and scale the result to cover the range [-1,1]
return 70.0 * (n0 + n1 + n2);
} // function
void main(void) {
float n = snoise(gl_TexCoord[0].st);
gl_FragColor = vec4(0.5 + 0.5 * vec3(n, n, n), 1.0); // Bias to range [0.0 : 1.0] and set fragment to fully opaque.
} // function