precision highp float; varying vec2 v_TexCoords; uniform float u_Time; uniform sampler2D u_NoiseBWPass; uniform vec2 u_NoiseBWPassSize; //Tweakables uniform float uCA; uniform float uHue; uniform float u_Freq; uniform float u_Amp; uniform float u_Offset; uniform float u_Speed; uniform bool u_Inverse; uniform bool u_NoiseOnly; #define TWO_PI (3.141592535*2.0) vec4 permute(vec4 x) { return mod((x * 34.0 + 1.0) * x, 289.0); } float snoise(vec3 v) { // First corner vec3 i = floor(v + dot(v, vec3(1.0/3.0))); vec3 x0 = v - i + dot(i, vec3(1.0/6.0)); // 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 ); // derivation of x0...x3 // x0 = x0 - 0.0 + 0.0 * 1.0/6.0; // x1 = x0 - i1 + 1.0 * 1.0/6.0; // x2 = x0 - i2 + 2.0 * 1.0/6.0; // x3 = x0 - 1.0 + 3.0 * 1.0/6.0; vec3 x1 = x0 - i1 + 1.0/6.0; vec3 x2 = x0 - i2 + 1.0/3.0; vec3 x3 = x0 - 0.5; // Permutations i = mod(i, 289.0); 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) vec4 j = mod(p, 49.0); vec4 x_ = floor(j * (1.0/7.0)); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ * (2.0/7.0) - (6.5/7.0); vec4 y = y_ * (2.0/7.0) - (6.5/7.0); vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); 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; // Normalise gradients vec3 p0 = normalize(vec3(a0.xy, h.x)); vec3 p1 = normalize(vec3(a0.zw, h.y)); vec3 p2 = normalize(vec3(a1.xy, h.z)); vec3 p3 = normalize(vec3(a1.zw, h.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 nnoise(vec2 uv) { float n = 10.0+sin(fract(u_Time*u_Speed)*TWO_PI); float aspect = u_NoiseBWPassSize.x/u_NoiseBWPassSize.y; uv = uv + vec2(u_Offset, u_Offset); float noise = snoise(vec3(uv*vec2(aspect, 1.0)* u_Freq * 10.0, n)); if (u_Inverse) { noise = 1.0-noise; } noise *= u_Amp; noise = smoothstep(0.0, 1.0, noise); return noise; } vec3 normalizeLength(vec2 v) { vec3 dir; dir.xy = v.xy; dir.z = dot(v.xy, v.xy); // normalize, storing length in z dir *= inversesqrt(dir.z); return dir; } float luma(vec3 color) { return dot(vec3(0.299, 0.587, 0.114), color); } vec3 rgb2hsv(vec3 color) { const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(color.bg, K.wz), vec4(color.gb, K.xy), step(color.b, color.g)); vec4 q = mix(vec4(p.xyw, color.r), vec4(color.r, p.yzx), step(p.x, color.r)); float d = q.x - min(q.w, q.y); const float e = 0.001; return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } vec3 hsv2rgb(vec3 color) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(color.xxx + K.xyz) * 6.0 - K.www); return color.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), color.y); } vec3 chromaticAberration(sampler2D samp, vec2 uv, float aberration, out vec3 original) { vec3 dir = normalizeLength(uv * 2.0 - 1.0); float weight = smoothstep(0.0, 1.0, dir.z*dir.z); vec2 duv = weight * dir.xy + 0.1; vec2 caUV = uv + aberration * duv * 3.0; vec4 cr = texture2D(samp, caUV); caUV = uv - aberration * duv; vec4 cg = texture2D(samp, caUV); original = texture2D(samp, uv).rgb; return vec3(cr.g, cg.g, original.g); } void main() { vec2 uv = vec2(v_TexCoords.x, 1.0-v_TexCoords.y); float noise = nnoise(uv);//1.0 - texture2D(u_NoiseAnimation, uv).r; vec3 bw; vec3 ca = chromaticAberration(u_NoiseBWPass, uv, uCA, bw); vec3 colHue = rgb2hsv(ca); ca = hsv2rgb(vec3(fract(colHue.x + uHue), colHue.y, colHue.z)); gl_FragColor = vec4(mix(bw, ca, noise).rgb, 1.); if (u_NoiseOnly) { gl_FragColor = vec4(vec3(noise), 1.0); } }