xxxxxxxxxx
70
// For shader workshops, check out
// https://hamoid.com/post/in-the-mood-for-shaders/
// :)
let img;
let fx;
let NUM_PARTICLES = 20;
function setup() {
createCanvas(600, 300, WEBGL);
fx = createShader(`
precision highp float;
attribute vec3 aPosition;
void main() {
gl_Position = vec4(aPosition, 1.0);
}`, `
precision highp float;
uniform sampler2D tex;
float distToLine(vec2 p, vec2 a, vec2 b) {
vec2 lineDir = b - a;
vec2 perpDir = vec2(lineDir.y, -lineDir.x);
vec2 dirToA = a - p;
return abs(dot(normalize(perpDir), dirToA));
}
float distToLineSegment(vec2 p, vec2 a, vec2 b) {
vec2 n = b - a;
vec2 pa = a - p;
float c = dot( n, pa );
// Closest point is a
if ( c > 0.0 ) return dot( pa, pa );
vec2 bp = p - b;
// Closest point is b
if ( dot( n, bp ) > 0.0 ) return dot( bp, bp );
// Closest point is between a and b
vec2 e = pa - n * (c / dot( n, n ));
return dot( e, e );
}
void main() {
float bri = 0.0;
float maxBri = 0.001; // adjust depending on the number of particles
vec2 pos = gl_FragCoord.xy / 300.0;
const float dx = 1.0/${NUM_PARTICLES}.0;
vec2 lastParticle = texture2D(tex, vec2(0.0, 0.0)).xy;
for(float x=dx; x<1.0; x+=dx) {
vec2 particle = texture2D(tex, vec2(x+dx, 0.0)).xy;
bri += maxBri / distToLine(pos, lastParticle, particle);
lastParticle = particle;
}
gl_FragColor = vec4(vec3(bri), 1.0);
}`);
noStroke();
shader(fx);
img = createImage(NUM_PARTICLES, 1);
}
function draw() {
img.loadPixels();
let t = millis() / 5000.0;
for (let x = 0; x < img.width; x++) {
img.pixels[x*4+0] = floor(256 * noise(x * 3.33 + t)); // R
img.pixels[x*4+1] = floor(256 * noise(t - x * 5.55)); // G
//img.pixels[x*4+2] = floor(random(256)); // B
img.pixels[x*4+3] = 255; // I don't understand the effect of this. Try 5. // A
}
img.updatePixels();
fx.setUniform('tex', img);
quad(-1, -1, 1, -1, 1, 1, -1, 1);
}