Created
June 11, 2019 03:30
-
-
Save loopervfx/59c3f668a9602d179f95e0f2982519d7 to your computer and use it in GitHub Desktop.
Touchdesigner perlin + simplex noise
This file contains hidden or 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 | |
#extension GL_NV_gpu_shader5 : enable | |
#extension GL_NV_bindless_texture : enable | |
#extension GL_ARB_shading_language_include : enable | |
/** BEGIN TD COMMON UTIL UNIFORMS Garbagesdmwk7**/ | |
uniform sampler2D sTDNoiseMap; | |
uniform sampler1D sTDSineLookup; | |
uniform sampler2D sTDWhite2D; | |
uniform sampler3D sTDWhite3D; | |
uniform sampler2DArray sTDWhite2DArray; | |
uniform samplerCube sTDWhiteCube; | |
/** END TD COMMON UTIL UNIFORMS Garbagexcmvcxm**/ | |
#define ONE 0.00390625 | |
#define ONEHALF 0.001953125 | |
float TDFade(float t) | |
{ | |
return t*t*t*(t*(t*6.0-15.0)+10.0); | |
} | |
uniform sampler2D sTDPermTexture; | |
uniform sampler2D sTDGradTexture; | |
uniform sampler1D sTDSimplexTexture; | |
float TDPerlinNoise(vec2 P) | |
{ | |
vec2 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled and offset for texture lookup; | |
vec2 Pf = fract(P); // Fractional part for interpolation; | |
// Noise contribution from lower left corner; | |
vec2 grad00 = texture(sTDPermTexture, Pi).rg * 4.0 - 1.0; | |
float n00 = dot(grad00, Pf); | |
// Noise contribution from lower right corner; | |
vec2 grad10 = texture(sTDPermTexture, Pi + vec2(ONE, 0.0)).rg * 4.0 - 1.0; | |
float n10 = dot(grad10, Pf - vec2(1.0, 0.0)); | |
// Noise contribution from upper left corner; | |
vec2 grad01 = texture(sTDPermTexture, Pi + vec2(0.0, ONE)).rg * 4.0 - 1.0; | |
float n01 = dot(grad01, Pf - vec2(0.0, 1.0)); | |
// Noise contribution from upper right corner; | |
vec2 grad11 = texture(sTDPermTexture, Pi + vec2(ONE, ONE)).rg * 4.0 - 1.0; | |
float n11 = dot(grad11, Pf - vec2(1.0, 1.0)); | |
// Blend contributions along x; | |
vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), TDFade(Pf.x)); | |
// Blend contributions along y; | |
float n_xy = mix(n_x.x, n_x.y, TDFade(Pf.y)); | |
// Were done, return the final noise value.; | |
return n_xy; | |
} | |
float TDPerlinNoise(vec3 P) | |
{ | |
vec3 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel | |
vec3 Pf = fract(P); // Fractional part for interpolation | |
float perm00 = texture(sTDPermTexture, Pi.xy).a ; | |
vec3 grad000 = texture(sTDPermTexture, vec2(perm00, Pi.z)).rgb * 4.0 - 1.0; | |
float n000 = dot(grad000, Pf); | |
vec3 grad001 = texture(sTDPermTexture, vec2(perm00, Pi.z + ONE)).rgb * 4.0 - 1.0; | |
float n001 = dot(grad001, Pf - vec3(0.0, 0.0, 1.0)); | |
float perm01 = texture(sTDPermTexture, Pi.xy + vec2(0.0, ONE)).a ; | |
vec3 grad010 = texture(sTDPermTexture, vec2(perm01, Pi.z)).rgb * 4.0 - 1.0; | |
float n010 = dot(grad010, Pf - vec3(0.0, 1.0, 0.0)); | |
vec3 grad011 = texture(sTDPermTexture, vec2(perm01, Pi.z + ONE)).rgb * 4.0 - 1.0; | |
float n011 = dot(grad011, Pf - vec3(0.0, 1.0, 1.0)); | |
float perm10 = texture(sTDPermTexture, Pi.xy + vec2(ONE, 0.0)).a ; | |
vec3 grad100 = texture(sTDPermTexture, vec2(perm10, Pi.z)).rgb * 4.0 - 1.0; | |
float n100 = dot(grad100, Pf - vec3(1.0, 0.0, 0.0)); | |
vec3 grad101 = texture(sTDPermTexture, vec2(perm10, Pi.z + ONE)).rgb * 4.0 - 1.0; | |
float n101 = dot(grad101, Pf - vec3(1.0, 0.0, 1.0)); | |
float perm11 = texture(sTDPermTexture, Pi.xy + vec2(ONE, ONE)).a ; | |
vec3 grad110 = texture(sTDPermTexture, vec2(perm11, Pi.z)).rgb * 4.0 - 1.0; | |
float n110 = dot(grad110, Pf - vec3(1.0, 1.0, 0.0)); | |
vec3 grad111 = texture(sTDPermTexture, vec2(perm11, Pi.z + ONE)).rgb * 4.0 - 1.0; | |
float n111 = dot(grad111, Pf - vec3(1.0, 1.0, 1.0)); | |
vec4 n_x = mix(vec4(n000, n001, n010, n011), | |
vec4(n100, n101, n110, n111), TDFade(Pf.x)); | |
vec2 n_xy = mix(n_x.xy, n_x.zw, TDFade(Pf.y)); | |
float n_xyz = mix(n_xy.x, n_xy.y, TDFade(Pf.z)); | |
return n_xyz; | |
} | |
float TDPerlinNoise(vec4 P) | |
{ | |
vec4 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel | |
// and offset 1/2 texel to sample texel centers | |
vec4 Pf = fract(P); // Fractional part for interpolation | |
// n0000 is the noise contribution from (x=0, y=0, z=0, w=0), and so on | |
float perm00xy = texture(sTDPermTexture, Pi.xy).a ; | |
float perm00zw = texture(sTDPermTexture, Pi.zw).a ; | |
vec4 grad0000 = texture(sTDGradTexture, vec2(perm00xy, perm00zw)).rgba * 4.0 -1.0; | |
float n0000 = dot(grad0000, Pf); | |
float perm01zw = texture(sTDPermTexture, Pi.zw + vec2(0.0, ONE)).a ; | |
vec4 grad0001 = texture(sTDGradTexture, vec2(perm00xy, perm01zw)).rgba * 4.0 - 1.0; | |
float n0001 = dot(grad0001, Pf - vec4(0.0, 0.0, 0.0, 1.0)); | |
float perm10zw = texture(sTDPermTexture, Pi.zw + vec2(ONE, 0.0)).a ; | |
vec4 grad0010 = texture(sTDGradTexture, vec2(perm00xy, perm10zw)).rgba * 4.0 - 1.0; | |
float n0010 = dot(grad0010, Pf - vec4(0.0, 0.0, 1.0, 0.0)); | |
float perm11zw = texture(sTDPermTexture, Pi.zw + vec2(ONE, ONE)).a ; | |
vec4 grad0011 = texture(sTDGradTexture, vec2(perm00xy, perm11zw)).rgba * 4.0 - 1.0; | |
float n0011 = dot(grad0011, Pf - vec4(0.0, 0.0, 1.0, 1.0)); | |
float perm01xy = texture(sTDPermTexture, Pi.xy + vec2(0.0, ONE)).a ; | |
vec4 grad0100 = texture(sTDGradTexture, vec2(perm01xy, perm00zw)).rgba * 4.0 - 1.0; | |
float n0100 = dot(grad0100, Pf - vec4(0.0, 1.0, 0.0, 0.0)); | |
vec4 grad0101 = texture(sTDGradTexture, vec2(perm01xy, perm01zw)).rgba * 4.0 - 1.0; | |
float n0101 = dot(grad0101, Pf - vec4(0.0, 1.0, 0.0, 1.0)); | |
vec4 grad0110 = texture(sTDGradTexture, vec2(perm01xy, perm10zw)).rgba * 4.0 - 1.0; | |
float n0110 = dot(grad0110, Pf - vec4(0.0, 1.0, 1.0, 0.0)); | |
vec4 grad0111 = texture(sTDGradTexture, vec2(perm01xy, perm11zw)).rgba * 4.0 - 1.0; | |
float n0111 = dot(grad0111, Pf - vec4(0.0, 1.0, 1.0, 1.0)); | |
float perm10xy = texture(sTDPermTexture, Pi.xy + vec2(ONE, 0.0)).a ; | |
vec4 grad1000 = texture(sTDGradTexture, vec2(perm10xy, perm00zw)).rgba * 4.0 - 1.0; | |
float n1000 = dot(grad1000, Pf - vec4(1.0, 0.0, 0.0, 0.0)); | |
vec4 grad1001 = texture(sTDGradTexture, vec2(perm10xy, perm01zw)).rgba * 4.0 - 1.0; | |
float n1001 = dot(grad1001, Pf - vec4(1.0, 0.0, 0.0, 1.0)); | |
vec4 grad1010 = texture(sTDGradTexture, vec2(perm10xy, perm10zw)).rgba * 4.0 - 1.0; | |
float n1010 = dot(grad1010, Pf - vec4(1.0, 0.0, 1.0, 0.0)); | |
vec4 grad1011 = texture(sTDGradTexture, vec2(perm10xy, perm11zw)).rgba * 4.0 - 1.0; | |
float n1011 = dot(grad1011, Pf - vec4(1.0, 0.0, 1.0, 1.0)); | |
float perm11xy = texture(sTDPermTexture, Pi.xy + vec2(ONE, ONE)).a ; | |
vec4 grad1100 = texture(sTDGradTexture, vec2(perm11xy, perm00zw)).rgba * 4.0 - 1.0; | |
float n1100 = dot(grad1100, Pf - vec4(1.0, 1.0, 0.0, 0.0)); | |
vec4 grad1101 = texture(sTDGradTexture, vec2(perm11xy, perm01zw)).rgba * 4.0 - 1.0; | |
float n1101 = dot(grad1101, Pf - vec4(1.0, 1.0, 0.0, 1.0)); | |
vec4 grad1110 = texture(sTDGradTexture, vec2(perm11xy, perm10zw)).rgba * 4.0 - 1.0; | |
float n1110 = dot(grad1110, Pf - vec4(1.0, 1.0, 1.0, 0.0)); | |
vec4 grad1111 = texture(sTDGradTexture, vec2(perm11xy, perm11zw)).rgba * 4.0 - 1.0; | |
float n1111 = dot(grad1111, Pf - vec4(1.0, 1.0, 1.0, 1.0)); | |
// Blend contributions along x | |
float TDFadex = TDFade(Pf.x); | |
vec4 n_x0 = mix(vec4(n0000, n0001, n0010, n0011), | |
vec4(n1000, n1001, n1010, n1011), TDFadex); | |
vec4 n_x1 = mix(vec4(n0100, n0101, n0110, n0111), | |
vec4(n1100, n1101, n1110, n1111), TDFadex); | |
// Blend contributions along y | |
vec4 n_xy = mix(n_x0, n_x1, TDFade(Pf.y)); | |
// Blend contributions along z | |
vec2 n_xyz = mix(n_xy.xy, n_xy.zw, TDFade(Pf.z)); | |
// Blend contributions along w | |
float n_xyzw = mix(n_xyz.x, n_xyz.y, TDFade(Pf.w)); | |
// Were done, return the final noise value. | |
return n_xyzw; | |
} | |
float TDSimplexNoise(vec2 P) | |
{ | |
// Skew and unskew factors are a bit hairy for 2D, so define them as constants | |
// This is (sqrt(3.0)-1.0)/2.0 | |
#define F2 0.366025403784 | |
// This is (3.0-sqrt(3.0))/6.0 | |
#define G2 0.211324865405 | |
// Skew the (x,y) space to determine which cell of 2 simplices were 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 were 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 = texture(sTDPermTexture, 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); | |
} | |
// Noise contribution from middle corner | |
vec2 Pf1 = Pf0 - o1 + G2; | |
vec2 grad1 = texture(sTDPermTexture, 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); | |
} | |
// Noise contribution from last corner | |
vec2 Pf2 = Pf0 - vec2(1.0-2.0*G2); | |
vec2 grad2 = texture(sTDPermTexture, 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); | |
} | |
// Sum up and scale the result to cover the range [-1,1] | |
return 70.0 * (n0 + n1 + n2); | |
} | |
float TDSimplexNoise(vec3 P) | |
{ | |
// The skewing and unskewing factors are much simpler for the 3D case | |
#define F3 0.333333333333 | |
#define G3 0.166666666667 | |
// Skew the (x,y,z) space to determine which cell of 6 simplices were in | |
float s = (P.x + P.y + P.z) * F3; // Factor for 3D skewing | |
vec3 Pi = floor(P + s); | |
float t = (Pi.x + Pi.y + Pi.z) * G3; | |
vec3 P0 = Pi - t; // Unskew the cell origin back to (x,y,z) space | |
Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup | |
vec3 Pf0 = P - P0; // The x,y distances from the cell origin | |
// For the 3D case, the simplex shape is a slightly irregular tetrahedron. | |
// To find out which of the six possible tetrahedra were in, we need to | |
// determine the magnitude ordering of x, y and z components of Pf0. | |
// The method below is explained briefly in the C code. It uses a small | |
// 1D texture as a lookup table. The table is designed to work for both | |
// 3D and 4D noise, so only 8 (only 6, actually) of the 64 indices are | |
// used here. | |
float c1 = (Pf0.x > Pf0.y) ? 0.5078125 : 0.0078125; // 1/2 + 1/128 | |
float c2 = (Pf0.x > Pf0.z) ? 0.25 : 0.0; | |
float c3 = (Pf0.y > Pf0.z) ? 0.125 : 0.0; | |
float sindex = c1 + c2 + c3; | |
vec3 offsets = texture(sTDSimplexTexture, sindex).rgb; | |
vec3 o1 = step(0.375, offsets); | |
vec3 o2 = step(0.125, offsets); | |
// Noise contribution from simplex origin | |
float perm0 = texture(sTDPermTexture, Pi.xy).a; | |
vec3 grad0 = texture(sTDPermTexture, vec2(perm0, Pi.z)).rgb * 4.0 - 1.0; | |
float t0 = 0.6 - dot(Pf0, Pf0); | |
float n0; | |
if (t0 < 0.0) n0 = 0.0; | |
else { | |
t0 *= t0; | |
n0 = t0 * t0 * dot(grad0, Pf0); | |
} | |
// Noise contribution from second corner | |
vec3 Pf1 = Pf0 - o1 + G3; | |
float perm1 = texture(sTDPermTexture, Pi.xy + o1.xy*ONE).a; | |
vec3 grad1 = texture(sTDPermTexture, vec2(perm1, Pi.z + o1.z*ONE)).rgb * 4.0 - 1.0; | |
float t1 = 0.6 - dot(Pf1, Pf1); | |
float n1; | |
if (t1 < 0.0) n1 = 0.0; | |
else { | |
t1 *= t1; | |
n1 = t1 * t1 * dot(grad1, Pf1); | |
} | |
// Noise contribution from third corner | |
vec3 Pf2 = Pf0 - o2 + 2.0 * G3; | |
float perm2 = texture(sTDPermTexture, Pi.xy + o2.xy*ONE).a; | |
vec3 grad2 = texture(sTDPermTexture, vec2(perm2, Pi.z + o2.z*ONE)).rgb * 4.0 - 1.0; | |
float t2 = 0.6 - dot(Pf2, Pf2); | |
float n2; | |
if (t2 < 0.0) n2 = 0.0; | |
else { | |
t2 *= t2; | |
n2 = t2 * t2 * dot(grad2, Pf2); | |
} | |
// Noise contribution from last corner | |
vec3 Pf3 = Pf0 - vec3(1.0-3.0*G3); | |
float perm3 = texture(sTDPermTexture, Pi.xy + vec2(ONE, ONE)).a; | |
vec3 grad3 = texture(sTDPermTexture, vec2(perm3, Pi.z + ONE)).rgb * 4.0 - 1.0; | |
float t3 = 0.6 - dot(Pf3, Pf3); | |
float n3; | |
if(t3 < 0.0) n3 = 0.0; | |
else { | |
t3 *= t3; | |
n3 = t3 * t3 * dot(grad3, Pf3); | |
} | |
// Sum up and scale the result to cover the range [-1,1] | |
return 32.0 * (n0 + n1 + n2 + n3); | |
} | |
float TDSimplexNoise(vec4 P) | |
{ | |
// The skewing and unskewing factors are hairy again for the 4D case | |
// This is (sqrt(5.0)-1.0)/4.0 | |
#define F4 0.309016994375 | |
// This is (5.0-sqrt(5.0))/20.0 | |
#define G4 0.138196601125 | |
// Skew the (x,y,z,w) space to determine which cell of 24 simplices were in | |
float s = (P.x + P.y + P.z + P.w) * F4; // Factor for 4D skewing | |
vec4 Pi = floor(P + s); | |
float t = (Pi.x + Pi.y + Pi.z + Pi.w) * G4; | |
vec4 P0 = Pi - t; // Unskew the cell origin back to (x,y,z,w) space | |
Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup | |
vec4 Pf0 = P - P0; // The x,y distances from the cell origin | |
// For the 4D case, the simplex is a 4D shape I wont even try to describe. | |
// To find out which of the 24 possible simplices were in, we need to | |
// determine the magnitude ordering of x, y, z and w components of Pf0. | |
// The method below is presented without explanation. It uses a small 1D | |
// texture as a lookup table. The table is designed to work for both | |
// 3D and 4D noise and contains 64 indices, of which only 24 are actually | |
// used. An extension to 5D would require a larger texture here. | |
float c1 = (Pf0.x > Pf0.y) ? 0.5078125 : 0.0078125; // 1/2 + 1/128 | |
float c2 = (Pf0.x > Pf0.z) ? 0.25 : 0.0; | |
float c3 = (Pf0.y > Pf0.z) ? 0.125 : 0.0; | |
float c4 = (Pf0.x > Pf0.w) ? 0.0625 : 0.0; | |
float c5 = (Pf0.y > Pf0.w) ? 0.03125 : 0.0; | |
float c6 = (Pf0.z > Pf0.w) ? 0.015625 : 0.0; | |
float sindex = c1 + c2 + c3 + c4 + c5 + c6; | |
vec4 offsets = texture(sTDSimplexTexture, sindex).rgba; | |
vec4 o1 = step(0.625, offsets); | |
vec4 o2 = step(0.375, offsets); | |
vec4 o3 = step(0.125, offsets); | |
// Noise contribution from simplex origin | |
float perm0xy = texture(sTDPermTexture, Pi.xy).a; | |
float perm0zw = texture(sTDPermTexture, Pi.zw).a; | |
vec4 grad0 = texture(sTDGradTexture, vec2(perm0xy, perm0zw)).rgba * 4.0 - 1.0; | |
float t0 = 0.6 - dot(Pf0, Pf0); | |
float n0; | |
if (t0 < 0.0) n0 = 0.0; | |
else { | |
t0 *= t0; | |
n0 = t0 * t0 * dot(grad0, Pf0); | |
} | |
// Noise contribution from second corner | |
vec4 Pf1 = Pf0 - o1 + G4; | |
o1 = o1 * ONE; | |
float perm1xy = texture(sTDPermTexture, Pi.xy + o1.xy).a; | |
float perm1zw = texture(sTDPermTexture, Pi.zw + o1.zw).a; | |
vec4 grad1 = texture(sTDGradTexture, vec2(perm1xy, perm1zw)).rgba * 4.0 - 1.0; | |
float t1 = 0.6 - dot(Pf1, Pf1); | |
float n1; | |
if (t1 < 0.0) n1 = 0.0; | |
else { | |
t1 *= t1; | |
n1 = t1 * t1 * dot(grad1, Pf1); | |
} | |
// Noise contribution from third corner | |
vec4 Pf2 = Pf0 - o2 + 2.0 * G4; | |
o2 = o2 * ONE; | |
float perm2xy = texture(sTDPermTexture, Pi.xy + o2.xy).a; | |
float perm2zw = texture(sTDPermTexture, Pi.zw + o2.zw).a; | |
vec4 grad2 = texture(sTDGradTexture, vec2(perm2xy, perm2zw)).rgba * 4.0 - 1.0; | |
float t2 = 0.6 - dot(Pf2, Pf2); | |
float n2; | |
if (t2 < 0.0) n2 = 0.0; | |
else { | |
t2 *= t2; | |
n2 = t2 * t2 * dot(grad2, Pf2); | |
} | |
// Noise contribution from fourth corner | |
vec4 Pf3 = Pf0 - o3 + 3.0 * G4; | |
o3 = o3 * ONE; | |
float perm3xy = texture(sTDPermTexture, Pi.xy + o3.xy).a; | |
float perm3zw = texture(sTDPermTexture, Pi.zw + o3.zw).a; | |
vec4 grad3 = texture(sTDGradTexture, vec2(perm3xy, perm3zw)).rgba * 4.0 - 1.0; | |
float t3 = 0.6 - dot(Pf3, Pf3); | |
float n3; | |
if (t3 < 0.0) n3 = 0.0; | |
else { | |
t3 *= t3; | |
n3 = t3 * t3 * dot(grad3, Pf3); | |
} | |
// Noise contribution from last corner | |
vec4 Pf4 = Pf0 - vec4(1.0-4.0*G4); | |
float perm4xy = texture(sTDPermTexture, Pi.xy + vec2(ONE, ONE)).a; | |
float perm4zw = texture(sTDPermTexture, Pi.zw + vec2(ONE, ONE)).a; | |
vec4 grad4 = texture(sTDGradTexture, vec2(perm4xy, perm4zw)).rgba * 4.0 - 1.0; | |
float t4 = 0.6 - dot(Pf4, Pf4); | |
float n4; | |
if(t4 < 0.0) n4 = 0.0; | |
else { | |
t4 *= t4; | |
n4 = t4 * t4 * dot(grad4, Pf4); | |
} | |
// Sum up and scale the result to cover the range [-1,1] | |
return 27.0 * (n0 + n1 + n2 + n3 + n4); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment