<canvas id="webgl" width="500" height="1758"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_position;
uniform mat4 u_modelViewMatrix;
uniform mat4 u_projectionMatrix;
void main() {
gl_Position = a_position;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
#extension GL_OES_standard_derivatives : enable
precision highp float;
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
uniform sampler2D u_noise;
vec2 getScreenSpace() {
vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / min(u_resolution.y, u_resolution.x);
return uv;
}
float sdLine( in vec2 p, in vec2 a, in vec2 b ) {
vec2 pa = p-a, ba = b-a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h );
}
const vec2 lw = vec2(.02, 1.);
const float multiplier = 2.;
const float inter = .8;
vec3 pattern(vec2 uv) {
vec3 colour = vec3(0.);
uv *= multiplier;
vec2 mouse = u_mouse * multiplier;
float line = sdLine(uv, vec2(0.), mouse);
float aa = fwidth(line)*lw.y;
float aa1 = fwidth(line*50.)*2.;
float sl = sin(line*50. - u_time*10.);
line = smoothstep(lw.x - aa, lw.x + aa, line);
colour = vec3(smoothstep(inter, inter-aa1, sl) * smoothstep(-inter, -inter+aa1, sl));
colour = mix(vec3(0.), colour, line);
float sx = sin((uv.y + u_mouse.x + sin(uv.x*10.) * .05) * 50.);
colour = min(colour, vec3(smoothstep(inter, inter-aa1, sx) * smoothstep(-inter, -inter+aa1, sx)));
return colour;
}
void main() {
vec2 uv = getScreenSpace();
vec3 colour = pattern(uv);
gl_FragColor = vec4(colour,1.0);
}
</script>
body {
margin:0;
}
canvas {
position: fixed;
}
console.clear();
const twodWebGL = new WTCGL(
document.querySelector('canvas#webgl'),
document.querySelector('script#vertexShader').textContent,
document.querySelector('script#fragmentShader').textContent,
window.innerWidth,
window.innerHeight,
2
);
twodWebGL.startTime = -100 + Math.random() * 50;
window.addEventListener('resize', () => {
twodWebGL.resize(window.innerWidth, window.innerHeight);
});
// track mouse move
let mousemoved = false;
let mousepos = [0,0];
const u_mousepos = twodWebGL.addUniform('mouse', WTCGL.TYPE_V2, mousepos);
window.addEventListener('pointermove', (e) => {
let ratio = window.innerHeight / window.innerWidth;
if(window.innerHeight > window.innerWidth) {
mousepos[0] = (e.pageX - window.innerWidth / 2) / window.innerWidth;
mousepos[1] = (e.pageY - window.innerHeight / 2) / window.innerHeight * -1 * ratio;
} else {
mousepos[0] = (e.pageX - window.innerWidth / 2) / window.innerWidth / ratio;
mousepos[1] = (e.pageY - window.innerHeight / 2) / window.innerHeight * -1;
}
twodWebGL.addUniform('mouse', WTCGL.TYPE_V2, mousepos);
mousemoved = true;
});
function runMouse(delta) {
if(!mousemoved) {
requestAnimationFrame(runMouse);
}
const d = delta * .0005;
mousepos[0] = Math.cos(d) * .5;
mousepos[1] = Math.sin(d * 2.) * .5;
twodWebGL.addUniform('mouse', WTCGL.TYPE_V2, mousepos);
}
requestAnimationFrame(runMouse);
// Load all our textures. We only initiate the instance once all images are loaded.
const textures = [
{
name: 'noise',
url: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/982762/noise.png',
type: WTCGL.IMAGETYPE_TILE,
img: null
}
];
const loadImage = function (imageObject) {
let img = document.createElement('img');
img.crossOrigin="anonymous";
return new Promise((resolve, reject) => {
img.addEventListener('load', (e) => {
imageObject.img = img;
resolve(imageObject);
});
img.addEventListener('error', (e) => {
reject(e);
});
img.src = imageObject.url
});
}
const loadTextures = function(textures) {
return new Promise((resolve, reject) => {
const loadTexture = (pointer) => {
if(pointer >= textures.length || pointer > 10) {
resolve(textures);
return;
};
const imageObject = textures[pointer];
const p = loadImage(imageObject);
p.then(
(result) => {
twodWebGL.addTexture(result.name, result.type, result.img);
},
(error) => {
console.log('error', error)
}).finally((e) => {
loadTexture(pointer+1);
});
}
loadTexture(0);
});
}
loadTextures(textures).then(
(result) => {
twodWebGL.initTextures();
// twodWebGL.render();
twodWebGL.running = true;
},
(error) => {
console.log('error');
}
);
View Compiled
This Pen doesn't use any external CSS resources.