Created
December 16, 2015 07:37
-
-
Save teknoman117/794971607fb2bd664d15 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 330 core | |
#extension GL_EXT_gpu_shader4: enable | |
#define X_NOISE_GEN 1619 | |
#define Y_NOISE_GEN 31337 | |
#define Z_NOISE_GEN 6971 | |
#define SEED_NOISE_GEN 1013 | |
#define SHIFT_NOISE_GEN 6 | |
#define DEFAULT_PERLIN_FREQUENCY 1.0 | |
#define DEFAULT_PERLIN_LACUNARITY 2.0 | |
#define DEFAULT_PERLIN_OCTAVE_COUNT 8 | |
#define DEFAULT_PERLIN_PERSISTENCE 0.5 | |
#define DEFAULT_PERLIN_SEED 80 | |
// Vector Table | |
uniform sampler1D vectorTable; | |
// test | |
uniform int frame; | |
// Input color from the vertex stage | |
in vec2 NoiseOut; | |
// Output color | |
out vec4 FinalColor; | |
/// Performs cubic interpolation between two values bound between two other values. | |
float CubicInterp (float n0, float n1, float n2, float n3, float a) | |
{ | |
float p = (n3 - n2) - (n0 - n1); | |
float q = (n0 - n1) - p; | |
float r = n2 - n0; | |
float s = n1; | |
return p * a * a * a + q * a * a + r * a + s; | |
} | |
/// Performs linear interpolation between two values. | |
float LinearInterp (float n0, float n1, float a) | |
{ | |
return ((1.0 - a) * n0) + (a * n1); | |
} | |
/// Performs linear interpolation between two values. | |
float LinearInterp2 (float n1, float n0, float a) | |
{ | |
return ((1.0 - a) * n0) + (a * n1); | |
} | |
/// Maps a value onto a cubic S-curve. | |
float SCurve3 (float a) | |
{ | |
return (a * a * (3.0 - 2.0 * a)); | |
} | |
/// Maps a value onto a quintic S-curve. | |
float SCurve5 (float a) | |
{ | |
float a3 = a * a * a; | |
float a4 = a3 * a; | |
float a5 = a4 * a; | |
return (6.0 * a5) - (15.0 * a4) + (10.0 * a3); | |
} | |
// Int32 range function | |
float MakeInt32Range (float n) | |
{ | |
if (n >= 1073741824.0) | |
{ | |
return (2.0 * mod (n, 1073741824.0)) - 1073741824.0; | |
} else if (n <= -1073741824.0) | |
{ | |
return (2.0 * mod (n, 1073741824.0)) + 1073741824.0; | |
} else | |
{ | |
return n; | |
} | |
} | |
float GradientNoise3D (sampler1D vTable, float fx, float fy, float fz, int ix, int iy, int iz, int seed) | |
{ | |
// Randomly generate a gradient vector given the integer coordinates of the | |
// input value. This implementation generates a random number and uses it | |
// as an index into a normalized-vector lookup table. | |
int vectorIndex = ((X_NOISE_GEN * ix) + (Y_NOISE_GEN * iy) + (Z_NOISE_GEN * iz) + (SEED_NOISE_GEN * seed)) & 0xffffffff; | |
vectorIndex ^= (vectorIndex >> SHIFT_NOISE_GEN); | |
vectorIndex &= 0xff; | |
// Fetch the random vector from the vector table | |
vec4 vGradient = texelFetch(vTable, vectorIndex, 0); | |
// Set up us another vector equal to the distance between the two vectors | |
// passed to this function. | |
float xvPoint = (fx - float(ix)); | |
float yvPoint = (fy - float(iy)); | |
float zvPoint = (fz - float(iz)); | |
// Now compute the dot product of the gradient vector with the distance | |
// vector. The resulting value is gradient noise. Apply a scaling value | |
// so that this noise value ranges from -1.0 to 1.0. | |
return ((vGradient.x * xvPoint) + (vGradient.y * yvPoint) + (vGradient.z * zvPoint)) * 2.12; | |
} | |
float GradientCoherentNoise3D (sampler1D vTable, float x, float y, float z, int seed) | |
{ | |
// Create a unit-length cube aligned along an integer boundary. This cube | |
// surrounds the input point. | |
int x0 = (x > 0.0 ? int(x) : int(x - 1)); | |
int x1 = x0 + 1; | |
int y0 = (y > 0.0? int(y): int(y - 1)); | |
int y1 = y0 + 1; | |
int z0 = (z > 0.0? int(z): int(z - 1)); | |
int z1 = z0 + 1; | |
// Map the difference between the coordinates of the input value and the | |
// coordinates of the cube's outer-lower-left vertex onto an S-curve. | |
float xs = SCurve3 (x - float(x0)); | |
float ys = SCurve3 (y - float(y0)); | |
float zs = SCurve3 (z - float(z0)); | |
// Now calculate the noise values at each vertex of the cube. To generate | |
// the coherent-noise value at the input point, interpolate these eight | |
// noise values using the S-curve value as the interpolant (trilinear | |
// interpolation.) | |
float n0, n1, ix0, ix1, iy0, iy1; | |
n0 = GradientNoise3D (vTable, x, y, z, x0, y0, z0, seed); | |
n1 = GradientNoise3D (vTable, x, y, z, x1, y0, z0, seed); | |
ix0 = LinearInterp (n0, n1, xs); | |
n0 = GradientNoise3D (vTable, x, y, z, x0, y1, z0, seed); | |
n1 = GradientNoise3D (vTable, x, y, z, x1, y1, z0, seed); | |
ix1 = LinearInterp (n0, n1, xs); | |
iy0 = LinearInterp (ix0, ix1, ys); | |
n0 = GradientNoise3D (vTable, x, y, z, x0, y0, z1, seed); | |
n1 = GradientNoise3D (vTable, x, y, z, x1, y0, z1, seed); | |
ix0 = LinearInterp (n0, n1, xs); | |
n0 = GradientNoise3D (vTable, x, y, z, x0, y1, z1, seed); | |
n1 = GradientNoise3D (vTable, x, y, z, x1, y1, z1, seed); | |
ix1 = LinearInterp (n0, n1, xs); | |
iy1 = LinearInterp (ix0, ix1, ys); | |
return LinearInterp (iy0, iy1, zs); | |
} | |
vec3 mod289(vec3 x) | |
{ | |
return x - floor(x * (1.0 / 289.0)) * 289.0; | |
} | |
vec4 mod289(vec4 x) | |
{ | |
return x - floor(x * (1.0 / 289.0)) * 289.0; | |
} | |
vec4 permute(vec4 x) | |
{ | |
return mod289(((x*34.0)+1.0)*x); | |
} | |
vec4 taylorInvSqrt(vec4 r) | |
{ | |
return 1.79284291400159 - 0.85373472095314 * r; | |
} | |
float snoise(vec3 v) | |
{ | |
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; | |
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); | |
// First corner | |
vec3 i = floor(v + dot(v, C.yyy) ); | |
vec3 x0 = v - i + dot(i, C.xxx) ; | |
// Other corners | |
vec3 g = step(x0.yzx, x0.xyz); | |
vec3 l = 1.0 - g; | |
vec3 i1 = min( g.xyz, l.zxy ); | |
vec3 i2 = max( g.xyz, l.zxy ); | |
// x0 = x0 - 0.0 + 0.0 * C.xxx; | |
// x1 = x0 - i1 + 1.0 * C.xxx; | |
// x2 = x0 - i2 + 2.0 * C.xxx; | |
// x3 = x0 - 1.0 + 3.0 * C.xxx; | |
vec3 x1 = x0 - i1 + C.xxx; | |
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y | |
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y | |
// Permutations | |
i = mod289(i); | |
vec4 p = permute( permute( permute( | |
i.z + vec4(0.0, i1.z, i2.z, 1.0 )) | |
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 )) | |
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 )); | |
// Gradients: 7x7 points over a square, mapped onto an octahedron. | |
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) | |
float n_ = 0.142857142857; // 1.0/7.0 | |
vec3 ns = n_ * D.wyz - D.xzx; | |
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) | |
vec4 x_ = floor(j * ns.z); | |
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) | |
vec4 x = x_ *ns.x + ns.yyyy; | |
vec4 y = y_ *ns.x + ns.yyyy; | |
vec4 h = 1.0 - abs(x) - abs(y); | |
vec4 b0 = vec4( x.xy, y.xy ); | |
vec4 b1 = vec4( x.zw, y.zw ); | |
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; | |
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; | |
vec4 s0 = floor(b0)*2.0 + 1.0; | |
vec4 s1 = floor(b1)*2.0 + 1.0; | |
vec4 sh = -step(h, vec4(0.0)); | |
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; | |
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; | |
vec3 p0 = vec3(a0.xy,h.x); | |
vec3 p1 = vec3(a0.zw,h.y); | |
vec3 p2 = vec3(a1.xy,h.z); | |
vec3 p3 = vec3(a1.zw,h.w); | |
//Normalise gradients | |
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); | |
p0 *= norm.x; | |
p1 *= norm.y; | |
p2 *= norm.z; | |
p3 *= norm.w; | |
// Mix final noise value | |
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); | |
m = m * m; | |
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), | |
dot(p2,x2), dot(p3,x3) ) ); | |
} | |
float perlin (sampler1D vTable, float x, float y, float z) | |
{ | |
float value = 0.0; | |
float signal = 0.0; | |
float curPersistence = 1.0; | |
float nx, ny, nz; | |
int seed; | |
x *= DEFAULT_PERLIN_FREQUENCY; | |
y *= DEFAULT_PERLIN_FREQUENCY; | |
z *= DEFAULT_PERLIN_FREQUENCY; | |
for (int curOctave = 0; curOctave < DEFAULT_PERLIN_OCTAVE_COUNT; curOctave++) | |
{ | |
// Make sure that these floating-point values have the same range as a 32- | |
// bit integer so that we can pass them to the coherent-noise functions. | |
nx = MakeInt32Range (x); | |
ny = MakeInt32Range (y); | |
nz = MakeInt32Range (z); | |
// Get the coherent-noise value from the input value and add it to the | |
// final result. | |
seed = (DEFAULT_PERLIN_SEED + curOctave) & 0xffffffff; | |
signal = snoise (vec3(nx, ny, nz + curOctave)); | |
//signal = GradientCoherentNoise3D (vTable, nx, ny, nz, seed); | |
value += signal * curPersistence; | |
// Prepare the next octave. | |
x *= DEFAULT_PERLIN_LACUNARITY; | |
y *= DEFAULT_PERLIN_LACUNARITY; | |
z *= DEFAULT_PERLIN_LACUNARITY; | |
curPersistence *= DEFAULT_PERLIN_PERSISTENCE; | |
} | |
return value; | |
} | |
// Main shader method | |
void main (void) | |
{ | |
// Get the height at a particular point | |
float h = perlin(vectorTable, NoiseOut.x * 2.5, NoiseOut.y * 2.5, (float(frame) / 60.0)); | |
//float h = GradientCoherentNoise3D(vectorTable, NoiseOut.x * 2.5, NoiseOut.y * 2.5, (float(frame) / 60.0), 0); | |
// Apply a gradient to this point | |
/*if(h >= -2 && h <= -0.25) | |
{ | |
float a = abs(h + 0.25) / 1.25; | |
FinalColor = vec4(0, 0, LinearInterp(1.0, 0.5, a), 1.0); | |
} | |
else if(h >= -0.25 && h <= 0.0) | |
{ | |
float a = abs(h) / 0.25; | |
FinalColor = vec4(0, LinearInterp2(0, 0.5, a), 1.0, 1.0); | |
} | |
else if(h >= 0 && h <= 0.0625) | |
{ | |
float a = h / 0.0625; | |
FinalColor = vec4(LinearInterp2(0.9375, 0, a), LinearInterp2(0.9375, 0.5, a), LinearInterp2(0.25, 1.0, a), 1.0); | |
} | |
else if(h >= 0.0625 && h <= 0.1250) | |
{ | |
float a = (h - 0.0625) / 0.0625; | |
FinalColor = vec4(LinearInterp2(0.125, 0.9375, a), LinearInterp2(0.625, 0.9375, a), LinearInterp2(0, 0.25, a), 1.0); | |
} | |
else if(h >= 0.1250 && h <= 0.3750) | |
{ | |
float a = (h - 0.1250) / 0.25; | |
FinalColor = vec4(LinearInterp2(0.875, 0.125, a), LinearInterp2(0.875, 0.625, a), 0, 1.0); | |
} | |
else if(h >= 0.3750 && h <= 0.7500) | |
{ | |
float a = (h - 0.3750) / 0.375; | |
FinalColor = vec4(LinearInterp2(0.5, 0.875, a), LinearInterp2(0.5, 0.875, a), LinearInterp2(0.5, 0, a), 1.0); | |
} | |
else if(h >= 0.7500 && h <= 2) | |
{ | |
float a = (h - 0.75) / 0.75; | |
FinalColor = vec4(LinearInterp2(1.0, 0.5, a), LinearInterp2(1.0, 0.5, a), LinearInterp2(1.0, 0.5, a), 1.0); | |
}*/ | |
FinalColor = vec4(vec3(1,1,1) * (h/4 + 0.5), 1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment