159 lines
3.4 KiB
JavaScript
159 lines
3.4 KiB
JavaScript
const warpSpeed = document.querySelector('#warpSpeed');
|
||
gsap.registerPlugin(ScrollTrigger);
|
||
gsap.to('#warpSpeed', {
|
||
value: 100,
|
||
ease: 'none',
|
||
scrollTrigger: { scrub: 0.1 }
|
||
});
|
||
const glsl = x => x;
|
||
|
||
const frag = glsl`
|
||
precision highp float;
|
||
uniform float time;
|
||
uniform float width;
|
||
uniform float height;
|
||
uniform float warpSpeed;
|
||
|
||
const float PI = 3.141592654;
|
||
const float DEG = PI / 180.0;
|
||
|
||
vec2 coords() {
|
||
float vmin = min(width, height);
|
||
return vec2((gl_FragCoord.x - width * .5) / vmin,
|
||
(gl_FragCoord.y - height * .5) / vmin);
|
||
}
|
||
|
||
vec2 rotate(vec2 p, float a) {
|
||
return vec2(p.x * cos(a) - p.y * sin(a),
|
||
p.x * sin(a) + p.y * cos(a));
|
||
}
|
||
|
||
vec2 repeat(in vec2 p, in vec2 c) {
|
||
return mod(p, c) - 0.5 * c;
|
||
}
|
||
|
||
// Distance functions by Inigo Quilez
|
||
// https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
|
||
float circle(in vec2 p, in vec2 pos, float radius) {
|
||
return length((p - pos)) - radius;
|
||
}
|
||
|
||
float symmetricDiff(float a, float b)
|
||
{
|
||
// (A ∪ B) \ (A ∩ B)
|
||
return max(min(a, b), -max(a, b));
|
||
}
|
||
|
||
float subtract(float a, float b)
|
||
{
|
||
return max(-a, b);
|
||
}
|
||
|
||
float circlesField(vec2 p, vec2 pCenter) {
|
||
float d = 1000.;
|
||
float s = .7;
|
||
for (int i = 9; i >= 0; i-= 2) {
|
||
d = min(d, circle(p, pCenter, float(i) * s));
|
||
d = subtract(circle(p, pCenter, float(i-1) * s), d);
|
||
}
|
||
return d;
|
||
}
|
||
|
||
float rectanglesField(vec2 p, vec2 pCenter) {
|
||
return 0.;
|
||
}
|
||
|
||
vec2 dotPattern(vec2 p) {
|
||
float w = 55. - max(0., warpSpeed / 6.);
|
||
return p + sin(p.x * w + time) * cos(p.y * w + time * .1 ) * .125;
|
||
}
|
||
|
||
float aa(float d) {
|
||
return smoothstep(.0, .05, d);
|
||
}
|
||
|
||
|
||
vec2 scene1(in vec2 p) {
|
||
p = rotate(p, -time * DEG);
|
||
float d0 = circlesField(p, vec2(sin(time * .3), cos(time * .2)));
|
||
float d1 = circlesField(p, vec2(sin(1. + time * .3), cos(1. + time * .2)));
|
||
return vec2(d0, d1);
|
||
}
|
||
|
||
vec2 scene2(in vec2 p) {
|
||
p = rotate(p, time * DEG);
|
||
vec2 q = vec2(cos(time * .2) * .7, sin(time * .3) * .7);
|
||
return vec2(
|
||
circle(mod(p, 4.) - 2., vec2(0.), 2.),
|
||
circle(mod(p + q, 4.) - 2., vec2(0.), 2.)
|
||
);
|
||
}
|
||
|
||
vec3 shade(in vec2 p)
|
||
{
|
||
float sceneId = floor(time / 1e3);
|
||
p = dotPattern(p);
|
||
vec3 background = vec3(.5 + sin(time * .05 + p.x * .1) * cos(p.y * .4 + p.x * .2), .2 + sin(time *.1 + p.x * .2) * cos(time * .1 + p.y * .13), .7);
|
||
vec3 white = vec3(1., 1., 1.);
|
||
vec3 black = vec3(0., 0., 0.);
|
||
vec2 s1 = scene1(p);
|
||
vec2 s2 = scene2(p);
|
||
float x = warpSpeed / 100.; // .5 + sin(time * .1) * .5
|
||
vec2 s = mix(s1, s2, x);
|
||
vec3 col0 = mix(white, black, aa(s.x));
|
||
vec3 col1 = mix(white, black, aa(s.y));
|
||
vec3 col = background + col0 - col1;
|
||
|
||
return col;
|
||
}
|
||
|
||
|
||
void main () {
|
||
vec2 p0 = coords();
|
||
float zoom = 7.;
|
||
vec3 col = shade(p0 * zoom);
|
||
gl_FragColor = vec4(col, 1.0);
|
||
}
|
||
`
|
||
|
||
const vert = glsl`
|
||
precision mediump float;
|
||
attribute vec2 position;
|
||
|
||
void main () {
|
||
gl_Position = vec4(position, 0, 1.0);
|
||
}
|
||
`
|
||
|
||
|
||
|
||
|
||
let texture = null;
|
||
|
||
const glea = new GLea({
|
||
shaders: [
|
||
GLea.fragmentShader(frag),
|
||
GLea.vertexShader(vert)
|
||
]
|
||
}).create();
|
||
|
||
function loop(time) {
|
||
const { gl } = glea;
|
||
glea.clear();
|
||
glea.uni('width', glea.width);
|
||
glea.uni('height', glea.height);
|
||
glea.uni('time', time * .005);
|
||
glea.uni('warpSpeed', parseFloat(warpSpeed.value));
|
||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||
requestAnimationFrame(loop);
|
||
}
|
||
|
||
function setup() {
|
||
const { gl } = glea;
|
||
window.addEventListener('resize', () => {
|
||
glea.resize();
|
||
});
|
||
loop(0);
|
||
}
|
||
|
||
setup(); |