<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

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://codepen.io/shubniggurath/pen/aPxLMx.js