<canvas></canvas>
<script type="x-shader/vertex">
precision mediump float;
attribute vec2 position;
void main () {
gl_Position = vec4(position, 0, 1.0);
}
</script>
<script type="x-shader/fragment">
precision highp float;
uniform float time;
uniform float width;
uniform float height;
const int ITERS = 120;
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;
}
vec3 palette(float x) {
return vec3(.5 + .5 * sin(time * .1+ x * 4.0), sin(time * .2 + x), sin(time *.1 + x + 1.0));
}
void main () {
vec2 p00 = coords();
vec2 p0 = rotate(p00, time *.05);
vec2 exp = vec2(p0 * .3)*.1;
vec2 logExp = log(exp);
vec3 col = palette(
.5 * sin(log(pow(length(exp), 3.0 +
1.0 * sin(time *.1))) + atan(exp.y, exp.x) + time*.2));
gl_FragColor = vec4(col, 1.0);
}
</script>
body {
margin: 0;
}
canvas {
display: block;
width: 100vw;
height: 100vh;
}
import GLea from "https://cdn.skypack.dev/glea";
const frag = document.querySelector('[type="x-shader/fragment"]').textContent;
const vert = document.querySelector('[type="x-shader/vertex"]').textContent;
const glea = new GLea({
shaders: [
GLea.fragmentShader(frag),
GLea.vertexShader(vert)
],
buffers: {
'position': GLea.buffer(2, [1, 1, -1, 1, 1,-1, -1,-1])
}
}).create();
window.addEventListener('resize', () => {
glea.resize();
});
function loop(time) {
const { gl } = glea;
glea.clear();
glea.uni('width', glea.width);
glea.uni('height', glea.height);
glea.uni('time', time * .005);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(loop);
}
loop(0);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.