#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); }