JSFiddle - React, Tailwind, and code Playground

by Paul West

CSS

body{
  overflow: hidden;
  margin: 0;
}

JavaScript

import * as THREE from "https://threejs.org/build/three.module.js";
import {OrbitControls} from "https://threejs.org/examples/jsm/controls/OrbitControls.js";
import {GUI} from "https://threejs.org/examples/jsm/libs/dat.gui.module.js";

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 0, 20);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

let controls = new OrbitControls(camera, renderer.domElement);

let g = new THREE.PlaneGeometry(20, 20);
let m = new THREE.MeshBasicMaterial({
	map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/uv_grid_opengl.jpg"),
  onBeforeCompile: shader => {
  	shader.uniforms.colorGray = m.userData.colorGray;
  	shader.fragmentShader = `
    	uniform float colorGray;
      ${shader.fragmentShader}
    `.replace(
    	`#include <map_fragment>`, // https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js
      `
      	#ifdef USE_MAP
          vec4 texelColor = texture2D( map, vUv );
          texelColor = mapTexelToLinear( texelColor );
          float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); 
          vec3 col = colorGray > 0.5 ? vec3(gray) : texelColor.rgb;
          diffuseColor *= vec4(col, texelColor.a);
        #endif
      `
    );
  	console.log(shader.fragmentShader)
  }
});
m.userData = {
	colorGray: {value: false}
}
let o = new THREE.Mesh(g, m);
scene.add(o);

let gui = new GUI();
gui.add(m.userData.colorGray, "value").name("grayscale");

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