// 3d noise fragment shader // vertex to fragment communication for noise shaders varying vec3 Nin; const float modulus = 61.; // modulus in random hash uniform sampler2D ntex; // noise texture void main() { // integer and fractional components of input, and fade blend function float fracArg = fract(modulus*Nin.z); float intArg = floor(modulus*Nin.z); // hash z & z+1 for noise offset. post-publication, I found that // including a small mutually prime multiplier improved the visual // quality of the hash near 0. I believe this is because 0^2, 1^2, // 2^2 are well under the hash modulus and close enough to appear // correlated. So 3*(z+1) = 3*z + 3 vec2 hash = mod(vec2(3.*intArg)+vec2(0,3.),modulus); hash = mod(hash*hash,modulus)/modulus; // lookup noise and blend slices vec2 g0, g1; g0 = texture2D(ntex, vec2(Nin.x,Nin.y+hash.x)).xy*2.-1.; g1 = texture2D(ntex, vec2(Nin.x,Nin.y+hash.y)).xy*2.-1.; float noise = mix(g0.r+g0.g*fracArg, g1.r+g1.g*(fracArg-1.), smoothstep(0.,1.,fracArg)); // combine with lighting gl_FragColor = gl_Color*(noise+1.)/2.; }