JSFiddle - React, Tailwind, and code Playground

HTML

<script src="//cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/loaders/GLTFLoader.js"></script>

<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv;

void main()
{
    vUv = uv;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_Position = projectionMatrix * mvPosition;
}
</script>

<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec2 u_mouse;
uniform vec2 u_resolution;
uniform sampler2D u_helmet_texture;

varying vec2 vUv;

void main() {
  vec2 st = gl_FragCoord.xy/u_resolution;
  float pct = 1.0 - distance(st, u_mouse);
  
  vec4 heatmap = vec4(pct*2.0, 0.1, 0.1, 0.7);
  vec4 helmet = texture2D(u_helmet_texture, vUv);
  
  vec4 color = mix(heatmap, helmet, .60);
  
  gl_FragColor = color;
}
</script>

CSS

body {
	  margin: 0;
}

JavaScript

var container, controls;
var camera, scene, renderer, uniforms;

init();
animate();

function init() {

  container = document.createElement( 'div' );
  document.body.appendChild( container );

  camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
  camera.position.set( - 1.8, 0.9, 2.7 );

  controls = new THREE.OrbitControls( camera );
  controls.target.set( 0, - 0.2, - 0.2 );
  controls.update();

  scene = new THREE.Scene();

  uniforms = {
    u_resolution: { value: new THREE.Vector2() },
    u_mouse: { value: new THREE.Vector2() },
    u_helmet_texture: { value: null }
  };

  // model
  var loader = new THREE.GLTFLoader();
  loader.load( 'https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', function ( gltf ) {
    
		gltf.scene.traverse( function ( child ) {
      
      if ( child.isMesh ) {
			
				uniforms.u_helmet_texture.value = child.material.map;
				child.material =  new THREE.ShaderMaterial({
					uniforms: uniforms,
					vertexShader: document.getElementById( 'vertexShader' ).textContent,
					fragmentShader: document.getElementById( 'fragmentShader' ).textContent
				});

      }
			
	 } );

   scene.add( gltf.scene );
		
  } );

  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  container.appendChild( renderer.domElement );

  window.addEventListener( 'resize', onWindowResize, false );

  onWindowResize();

  document.onmousemove = function(e){
    uniforms.u_mouse.value.x = e.pageX / window.innerWidth;
    uniforms.u_mouse.value.y = 1 - (e.pageY / window.innerHeight);
  };


}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  
  uniforms.u_resolution.value.x = renderer.domElement.width;
  uniforms.u_resolution.value.y = renderer.domElement.height;

  renderer.setSize(...