JSFiddle - React, Tailwind, and code Playground

by Cody Bennett

CSS

body {
  margin: 0;
}

canvas {
  display: block;
}

JavaScript

import * as THREE from 'https://unpkg.com/three/build/three.module.js';

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 10);
camera.position.z = 1;

const scene = new THREE.Scene();

const backgroundGeometry = new THREE.PlaneGeometry(2, 2, 1);
const backgroundMaterial = new THREE.RawShaderMaterial({
  vertexShader: `
    attribute vec3 position;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    varying vec2 vUv;
    void main() {
      gl_Position = vec4(position, 1.0);
      vUv = vec2(position.x, position.y) * 0.5 + 0.5;
    }
  `,
  fragmentShader: `
    precision mediump float;
    #pragma glslify: grain = require('glsl-film-grain')
    #pragma glslify: blend = require('glsl-blend-soft-light')

    uniform vec3 color1;
    uniform vec3 color2;
    uniform float aspect;
    uniform vec2 offset;
    uniform vec2 scale;
    uniform float noiseAlpha;
    uniform bool aspectCorrection;
    uniform float grainScale;
    uniform float grainTime;
    uniform vec2 smooth;

    varying vec2 vUv;

    void main() {
      vec2 q = vec2(vUv - 0.5);
      if (aspectCorrection) {
        q.x *= aspect;
      }
      q /= scale;
      q -= offset;
      float dst = length(q);
      dst = smoothstep(smooth.x, smooth.y, dst);
      vec3 color = mix(color1, color2, dst);

      if (noiseAlpha > 0.0 && grainScale > 0.0) {
        float gSize = 1.0 / grainScale;
        float g = grain(vUv, vec2(gSize * aspect, gSize), grainTime);
        vec3 noiseColor = blend(color, vec3(g));
        gl_FragColor.rgb = mix(color, noiseColor, noiseAlpha);
      } else {
        gl_FragColor.rgb = color;
      }

      gl_FragColor.a = 1.0;
    }
  `,
  side: THREE.DoubleSide,
  uniforms: {
    aspectCorrection: { type: 'i', value: false },
    aspect: { type:...