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...