xxxxxxxxxx
71
precision mediump float;
// Pixel position
varying vec2 pos;
// Uniforms set by filterShader
uniform sampler2D filter_background; // contains the image being filtered
uniform vec2 filter_res; // contains the image resolution in pixels
uniform float time_s;
// 2D Random with salt
float random (in vec2 st, in float salt) {
return fract(sin(dot(st, vec2(12.9898, 78.233) + salt)) * 43758.5453);
}
// 2D Noise based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in vec2 st, float scale, float salt) {
st *= scale;
vec2 i = floor(st);
vec2 f = fract(st);
// Four corners in 2D of a tile
float a = random(i, salt);
float b = random(i + vec2(1.0, 0.0), salt);
float c = random(i + vec2(0.0, 1.0), salt);
float d = random(i + vec2(1.0, 1.0), salt);
// Smooth Interpolation
// Cubic Hermine Curve. Same as SmoothStep()
vec2 u = f*f*(3.0-2.0*f);
// u = smoothstep(0.,1.,f);
// Mix 4 coorners percentages
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
void main() {
// Figure out how far a pixel is for x, y (z is 0 for convenience)
vec3 normalRes = vec3(1./filter_res, 0.);
// scroll image
float scroll_amt = 1. + noise(pos, 5., 2.);
vec2 sample_pos = pos + scroll_amt * normalRes.zy;
// Read colours of neighbour pixels (up, down, left, right)
vec4 neighbours = vec4(0., 0., 0., 0.);
neighbours += texture2D(filter_background, sample_pos + normalRes.xz);
neighbours += texture2D(filter_background, sample_pos - normalRes.xz);
neighbours += texture2D(filter_background, sample_pos + normalRes.zy);
neighbours += texture2D(filter_background, sample_pos - normalRes.zy);
// Average the neighbour values
vec4 col = neighbours/4.;
sample_pos.y += time_s; // scroll cooling map
// Subtract a bit to cool
float cooling = noise(sample_pos, 10., 0.) * 0.005;
col -= cooling;
col *= vec4(1., 0.99, 0.7, 1.);
gl_FragColor = col;
}