JSFiddle - React, Tailwind, and code Playground

by Paul West

HTML

<script src="https://cdn.jsdelivr.net/npm/three@0.93.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.93.0/examples/js/controls/OrbitControls.js"></script>
<script>
  function GridBoxGeometry(geometry, independent) {
    if (!(geometry instanceof THREE.BoxBufferGeometry)) {
      console.log("GridBoxGeometry: the parameter 'geometry' has to be of the type THREE.BoxBufferGeometry");
      return geometry;
    }
    independent = independent !== undefined ? independent : false;

    let newGeometry = new THREE.BoxBufferGeometry();
    let position = geometry.attributes.position;
    newGeometry.attributes.position = independent === false ? position : position.clone();

    let segmentsX = geometry.parameters.widthSegments || 1;
    let segmentsY = geometry.parameters.heightSegments || 1;
    let segmentsZ = geometry.parameters.depthSegments || 1;

    let startIndex = 0;
    let indexSide1 = indexSide(segmentsZ, segmentsY, startIndex);
    startIndex += (segmentsZ + 1) * (segmentsY + 1);
    let indexSide2 = indexSide(segmentsZ, segmentsY, startIndex);
    startIndex += (segmentsZ + 1) * (segmentsY + 1);
    let indexSide3 = indexSide(segmentsX, segmentsZ, startIndex);
    startIndex += (segmentsX + 1) * (segmentsZ + 1);
    let indexSide4 = indexSide(segmentsX, segmentsZ, startIndex);
    startIndex += (segmentsX + 1) * (segmentsZ + 1);
    let indexSide5 = indexSide(segmentsX, segmentsY, startIndex);
    startIndex += (segmentsX + 1) * (segmentsY + 1);
    let indexSide6 = indexSide(segmentsX, segmentsY, startIndex);

    let fullIndices = [];
    fullIndices = fullIndices.concat(indexSide1);
    fullIndices = fullIndices.concat(indexSide2);
    fullIndices = fullIndices.concat(indexSide3);
    fullIndices = fullIndices.concat(indexSide4);
    fullIndices = fullIndices.concat(indexSide5);
    fullIndices = fullIndices.concat(indexSide6);

    newGeometry.setIndex(fullIndices);

    function indexSide(x, y, shift) {
      let...

CSS

body {
  overflow: hidden;
  margin: 0;
}

JavaScript

videoTex.volume = 0;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(2, 1, 2).setLength(15);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x202020);
document.body.appendChild(renderer.domElement);

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

var frustFOV = 30;
var frustRatio = 16 / 9;
var frustPlane = 10;

var frustH = frustPlane * Math.sin(THREE.Math.degToRad(frustFOV * 0.5));
var frustW = frustH * frustRatio;
var frustPoints = [
	new THREE.Vector3(),
	new THREE.Vector3( -frustW,  frustH, -frustPlane ),
  new THREE.Vector3(  frustW,  frustH, -frustPlane ),
  new THREE.Vector3( -frustW, -frustH, -frustPlane ),
  new THREE.Vector3(  frustW, -frustH, -frustPlane )
];

var frustGeom = new THREE.BufferGeometry().setFromPoints(frustPoints);
frustGeom.setIndex([0,1, 0, 2, 0, 3, 0, 4, 1, 2, 2, 4, 4, 3, 3, 1]);
var frustumHelper = new THREE.LineSegments(frustGeom, new THREE.LineBasicMaterial({color: 0xff0000}));
frustumHelper.position.set(0, 0, 9);
frustumHelper.updateMatrixWorld();
scene.add(frustumHelper);

var screen = new THREE.Mesh(new THREE.BoxBufferGeometry(16, 9, 2), 
	new THREE.ShaderMaterial({
  	uniforms: {
    	baseColor: {value: new THREE.Color(0xcccccc)},
    	frustum: { value: [
      	new THREE.Vector3(),
        new THREE.Vector3(),
        new THREE.Vector3(),
        new THREE.Vector3(),
        new THREE.Vector3(),
        ]},
      tex: {value: new THREE.VideoTexture( videoTex )}
    },
    vertexShader: `
    	
      varying vec4 vWorldPos;
    	
      void main() {
        vWorldPos = modelMatrix * vec4(position, 1.0);
        gl_Position = projectionMatrix * viewMatrix * vWorldPos;
      }
    `,
    fragmentShader: `
    	uniform vec3 baseColor;
      uniform vec3 frustum[5];
      uniform sampler2D tex;
    	
      varying...