JSFiddle - React, Tailwind, and code Playground

by Paul West

HTML

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.5/dat.gui.min.js"></script>
<script>
  var vertexShader = `
    varying vec2 vUv;
    void main()	{
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
    }
  `;
  var fragmentShader = `
		//#extension GL_OES_standard_derivatives : enable
    
    varying vec2 vUv;
    uniform float thickness;
    uniform vec3 color;
   	
    float edgeFactor(vec2 p){
    	vec2 grid = abs(fract(p - 0.5) - 0.5) / fwidth(p) / thickness;
  		return min(grid.x, grid.y);
    }
    
    void main() {
			
      float a = clamp(edgeFactor(vUv), 0., 1.);
      
      vec3 c = mix(vec3(0), color, a);
      
      gl_FragColor = vec4(c, 1.0);
    }
  `;

</script>

CSS

body {
  overflow: hidden;
  margin: 0;
}

JavaScript

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(8, 16, 12);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target = new THREE.Vector3(0, 2.5, 0);
controls.update();

var geom = new THREE.BoxBufferGeometry();
geom.translate(0, 0.5, 0);

var material = new THREE.ShaderMaterial({
  uniforms: {
    thickness: {
    	value: 1.5
    },
    color: {
    	value: new THREE.Color()
    }
  },
  vertexShader: vertexShader,
  fragmentShader: fragmentShader,
  extensions: {derivatives: true}
});

for(let i = -4.5; i <= 4.5; i++){
	for(let j = -4.5; j <= 4.5; j++){
		let box = new THREE.Mesh( geom, material.clone() );
    box.material.uniforms.color.value.set(Math.random() * 0xffffff);
    box.scale.y = THREE.Math.randInt(1, 10);
    box.position.set(i, 0, j);
		scene.add( box );  	
  }
}


var gui = new dat.GUI();
gui.add(material.uniforms.thickness, "value", 1, 3).name("thickness");

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}