JSFiddle - React, Tailwind, and code Playground

by tfoller

HTML

<canvas id="main_canvas" style="border: solid 1px grey;" width=700 height=350></canvas>
<div>
<button id="bgrey">grey</button>
<button id="bgreyR601">greyR601</button>
<button id="bgreyR601S">greyR601S</button>
<button id="bgreyPS">greyPS</button>
<button id="reload">reload</button>
</div>
<script type="x-shader/x-function" id="SRGBLinear">
   vec3 SRGBLinear(vec3 rgb) {
      bvec3 lin = greaterThan(rgb, vec3(0.04045));
      float k1 = 1.0 / 1.055;
      float k2 = 1.0 / 12.92;
      // #version 300 es
      vec3 lRgb = mix(k2 * rgb, pow(k1 * (rgb + 0.055), vec3(2.4)), lin);
      for(int i = 0; i < 3; i++)
        lRgb[i] = lin[i] ? pow(k1 * (rgb[i] + 0.055), 2.4) : k2 * rgb[i];
      
      return lRgb;
   }
</script>
<script type="x-shader/x-function" id="linearRGB601">
   vec3 linearRGB601(vec3 rgb) { // Rec.601
      bvec3 lin = greaterThanEqual(rgb, vec3(0.018));
      vec3 lRgb;
      for(int i = 0; i < 3; i++)
         lRgb[i] = lin[i] ? 1.099 * pow(rgb[i], 0.45) - 0.099 : 4.5 * rgb[i];
      return lRgb;
   }
</script>
<script type="x-shader/x-function" id="greyR601">
   float greyR601(vec3 sRGB) {
      vec3 lRGB = pow(sRGB, vec3(2.2));
      vec3 rgb601 = linearRGB601(lRGB);
      vec3 luma = vec3(0.299, 0.587, 0.114);
     return dot(luma, rgb601);
   }
</script>
<script type="x-shader/x-function" id="greyR601S">
   float greyR601S(vec3 sRGB) {
      vec3 lRGB = SRGBLinear(sRGB);
      vec3 rgb601 = linearRGB601(lRGB);
      vec3 luma = vec3(0.299, 0.587, 0.114);
     return dot(luma, rgb601);
   }
</script>
<script type="x-shader/x-function" id="grey">
   float grey(vec3 sRGB) {
      vec3 lRGB = pow(sRGB, vec3(2.2));
      vec3 lumi = vec3(0.2126, 0.7152, 0.0722);
      float y = dot(lumi, lRGB);
      return pow(y, 1.0 / 2.2);
   }
</script>
<script type="x-shader/x-function" id="greyPS">
   float greyPS(vec3 sRGB) {
      // photoshop desaturate
      float bw = (min(sRGB.r, min(sRGB.g, sRGB.b)) + max(sRGB.r, max(sRGB.g, sRGB.b))) * 0.5;
     ...

CSS

body {
  background: #000;
}

button {
  padding: 3px;
  margin-right: 5px;
  cursor: pointer;
  filter: invert(1);
}

div {
  color: #ccc;
}

JavaScript

import * as THREE from 'https://alikim.com/_v1_jsm/three.module.js'
import {
  getShader
} from 'https://alikim.com/_v1_jsm/utils_three.js'

const get = (id) => document.getElementById(id);

const canvas = get('main_canvas');
const [w2, h2] = [canvas.width / 2, canvas.height / 2];
const renderer = new THREE.WebGLRenderer({
  antialias: false,
  alpha: true,
  canvas,
});
renderer.setPixelRatio(window.devicePixelRatio);

const [near, far] = [1, 1000];
const camera = new THREE.OrthographicCamera(-w2, w2, h2, -h2, near, far);

const render = () => {
  renderer.render(scene, camera)
};

THREE.Cache.enabled = false;
const texldr = new THREE.TextureLoader();

const geo = new THREE.PlaneBufferGeometry(350, 350, 1, 1);
const mat = new THREE.MeshBasicMaterial();

const quad = new THREE.Mesh(geo, mat);

let _map;
const loadMap = () => {
  _map = texldr.load(
    'https://source.unsplash.com/random/350x350',
    () => {
      mat.map = _map;
      mat.map.needsUpdate = true;
      render();
    }
  )
};
loadMap();

let _mode = 0;
const msh = new THREE.Mesh(
  geo,
  new THREE.ShaderMaterial({
    vertexShader: getShader('vs'),
    fragmentShader: getShader('fs'),
    uniforms: {
      map: {
        get value() {
          return _map
        }
      },
      mode: {
        get value() {
          return _mode
        }
      },
    },
  })
);

quad.position.x = w2 / 2;
msh.position.x = -w2 / 2;
camera.position.set(0, 0, 180);

const scene = new THREE.Scene().add(msh).add(quad);

get('bgrey').addEventListener('click', () => {
  _mode = 0;
  render();
});
get('bgreyR601').addEventListener('click', () => {
  _mode = 1;
  render();
});
get('bgreyR601S').addEventListener('click', () => {
  _mode = 2;
  render();
});
get('bgreyPS').addEventListener('click', () => {
  _mode = 3;
  render();
});
get('reload').addEventListener('click', ()=>{location.reload()});//loadMap);