<script id="vertSun" type="x-shader/x-vertex">
  varying vec2 vUv;
  void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
  }
</script>

<script id="fragSun" type="x-shader/x-fragment">
  uniform vec3 color1;
  uniform vec3 color2;

  varying vec2 vUv;

  void main() {
    gl_FragColor = vec4(mix(color1, color2, vUv.y), 1.0);
  }
</script>

<script id="fragPlane" type="x-shader/x-fragment">
  uniform vec3 color1;
  uniform vec3 color2;

  varying vec2 vUv;

  void main() {
    gl_FragColor = vec4(mix(color1, color2, vUv.x), 1.0);
  }
</script>

<div class="aon">
  <a href="https://codepen.io/collection/DpwaJW/" target="_blank">
    <span>View Collection</span>
    <span>Art of Noise</span>
  </a>
</div>
canvas{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 2px solid #fff;
}

@import url('https://fonts.googleapis.com/css?family=Cinzel|Cinzel+Decorative');

html, body{
  overflow: hidden;
  background: #000;
  padding: 0px;
  margin: 0px;
}

.aon {
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 1001;
  
  & a{
    position: relative;
    display: inline-block;
    outline: none;
    margin: 0 0px;
    padding: 15px 10px;
    color: #fff;
    text-decoration: none;
    font-family: Cinzel;
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-weight: 400;
    text-shadow: 0 0 1px rgba(255,255,255,0.3);
    font-size: 1em;
    
    &:focus::before,
    &:hover::before{
      height: 6px;
    }
    
    &:hover::before,
    &:hover::after,
    &:focus::before,
    &:focus::after {
      opacity: 1;
      -webkit-transform: translateY(0px);
      -moz-transform: translateY(0px);
      transform: translateY(0px);
    }
    
    &:hover span:last-child,
    &:focus span:last-child {
      opacity: 1;
      -webkit-transform: translateY(0%);
      -moz-transform: translateY(0%);
      transform: translateY(0%);
    }
    
    & span{
      color: #fff !important;
      
      &:first-child{
        z-index: 2;
        display: block;
        font-weight: 300;
      }
      
      &:last-child{
        z-index: 1;
        display: block;
        padding: 8px 0 0 0;
        color: rgba(0,0,0,0.4);
        text-shadow: none;
        text-transform: none;
        font-style: italic;
        font-size: 1.2em;
        font-family: Cinzel Decorative;
        font-weight: 600;
        opacity: 0;
        -webkit-transition: -webkit-transform 0.3s, opacity 0.3s;
        -moz-transition: -moz-transform 0.3s, opacity 0.3s;
        transition: transform 0.3s, opacity 0.3s;
        -webkit-transform: translateY(-100%);
        -moz-transform: translateY(-100%);
        transform: translateY(-100%);
      }
    }
    
    &::before,
    &::after{
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 1px;
      background: #fff;
      content: '';
      opacity: 0.2;
      -webkit-transition: opacity 0.3s, height 0.3s;
      -moz-transition: opacity 0.3s, height 0.3s;
      transition: opacity 0.3s, height 0.3s;
    }
    
    &::after{
      top: 100%;
      opacity: 0;
      -webkit-transition: -webkit-transform 0.3s, opacity 0.3s;
      -moz-transition: -moz-transform 0.3s, opacity 0.3s;
      transition: transform 0.3s, opacity 0.3s;
      -webkit-transform: translateY(-10px);
      -moz-transform: translateY(-10px);
      transform: translateY(-10px);
    }
    
    &:hover{
      outline: none;
    }
  }
}
View Compiled
var scene, camera, renderer, controls;
nt = 0;
var res = {x:622, y:350};
config = {
  planeX: 800,
  planeY: 800,
  planeZ: 70,
  xNoiseScale: 200,
  yNoiseScale: 200,
  zNoiseScale: 200,
  noiseSpeed: 0.002,
  cameraSpeed: 1
}

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, res.x/res.y, 0.1, 10000);
camera.position.x = 400;
camera.position.y = 100;
camera.position.z = 0;
camera.lookAt(0,0,0);

var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setClearColor("#000000");
renderer.setSize(res.x, res.y);
document.body.appendChild(renderer.domElement);

var geo = new THREE.PlaneBufferGeometry(config.planeX,config.planeY,20,20);
var mat = new THREE.MeshLambertMaterial({color: 0x000000, side: THREE.DoubleSide});
var plane = new THREE.Mesh(geo, mat);
scene.add(plane);
plane.position.z = 0;
plane.position.x = 0;
plane.position.y = 0;
plane.rotateX(90*(Math.PI/180));

var mat = new THREE.ShaderMaterial({
  uniforms: {
    color1: {value: new THREE.Color("#f222ff")},
    color2: {value: new THREE.Color("#8c1eff")}
  },
  vertexShader: document.getElementById("vertSun").innerHTML,
  fragmentShader: document.getElementById("fragPlane").innerHTML,
  wireframe: true
});
var plane2 = new THREE.Mesh(geo, mat);
scene.add(plane2);
plane2.position.z = 0;
plane2.position.x = 0;
plane2.position.y = 0;
plane2.rotateX(90*(Math.PI/180));

var geo = new THREE.CircleGeometry(100, 50);
var mat = new THREE.ShaderMaterial({
  uniforms: {
    color1: {value: new THREE.Color("#ff2975")},
    color2: {value: new THREE.Color("#f222ff")}
  },
  vertexShader: document.getElementById("vertSun").innerHTML,
  fragmentShader: document.getElementById("fragSun").innerHTML
});
var sun = new THREE.Mesh(geo,mat);
scene.add(sun);
sun.rotateY(90*(Math.PI/180));
sun.position.x = -400;
sun.position.y = 50;
sun.position.z = 0;

var starsGeometry = new THREE.Geometry();
for(var i=0; i<3000; i++){
  var star = new THREE.Vector3();
  star.x = THREE.Math.randFloatSpread(3000);
  star.y = THREE.Math.randFloatSpread(3000);
  star.z = THREE.Math.randFloatSpread(3000);
  starsGeometry.vertices.push(star);
}
var starsMaterial = new THREE.PointsMaterial({color: 0xFFFFFF});
var starField = new THREE.Points(starsGeometry,starsMaterial);
scene.add(starField);

//ambientLight = new THREE.AmbientLight("#ffffff"), scene.add(ambientLight);
//scene.fog = new THREE.FogExp2(0x666666, 0.005);

function animate() {
  var gpL = plane.geometry.attributes.position;
  nt += config.noiseSpeed;
  for (var i=0; i<gpL.array.length; i+=3) {
    var zns;
    i<=816&&i>=504?zns=0:zns=config.zNoiseScale;
    gpL.array[i+2] = -Math.abs(noise.perlin3(gpL.array[i]/config.yNoiseScale,gpL.array[i+1]/config.xNoiseScale, nt)*(zns));
  }
  gpL.needsUpdate = true;
}

var render = function () {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
  animate();
};
render();
// 100! 😃

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js
  2. https://codepen.io/Tibixx/pen/BbBxRG.js