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>
Object.assign(THREE.PlaneBufferGeometry.prototype, {
toGrid: function() {
let segmentsX = this.parameters.widthSegments || 1;
let segmentsY = this.parameters.heightSegments || 1;
let indices = [];
for (let i = 0; i < segmentsY + 1; i++) {
let index11 = 0;
let index12 = 0;
for (let j = 0; j < segmentsX; j++) {
index11 = (segmentsX + 1) * i + j;
index12 = index11 + 1;
let index21 = index11;
let index22 = index11 + (segmentsX + 1);
indices.push(index11, index12);
if (index22 < ((segmentsX + 1) * (segmentsY + 1) - 1)) {
indices.push(index21, index22);
}
}
if ((index12 + segmentsX + 1) <= ((segmentsX + 1) * (segmentsY + 1) - 1)) {
indices.push(index12, index12 + segmentsX + 1);
}
}
this.setIndex(indices);
return this;
}
});
</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(-15, 5, 2).setLength(25);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
scene.add(new THREE.GridHelper(10, 10));
// "screen"
var planeGeom = new THREE.PlaneBufferGeometry(8, 4, 4, 4).toGrid();
planeGeom.translate(0, 0, 20);
var attrPosition = planeGeom.attributes.position;
var tempVector = new THREE.Vector3();
for (let i = 0; i < attrPosition.count; i++){
tempVector.fromBufferAttribute(attrPosition, i).setLength(20);
attrPosition.setXYZ(i, tempVector.x, tempVector.y, tempVector.z);
}
var plane = new THREE.LineSegments(planeGeom, new THREE.LineBasicMaterial({color: "yellow"}));
scene.add(plane);
// "frustum"
var pyramidGeom = new THREE.BufferGeometry();
pyramidGeom.addAttribute('position', new THREE.BufferAttribute( new Float32Array(15), 3));
pyramidGeom.attributes.position.setXYZ(0, 0, 0, 0);
pyramidGeom.attributes.position.copyAt(1, attrPosition, 0);
pyramidGeom.attributes.position.copyAt(2, attrPosition, 4);
pyramidGeom.attributes.position.copyAt(3, attrPosition, 20);
pyramidGeom.attributes.position.copyAt(4, attrPosition, 24);
pyramidGeom.setIndex([0,1,0,2,0,3,0,4]);
var pyramid = new THREE.LineSegments(pyramidGeom, new THREE.LineBasicMaterial({color: "red"}));
plane.add(pyramid);
plane.position.set(0, 3, 0);
var clock = new THREE.Clock();
var time = 0;
render();
function render() {
requestAnimationFrame(render);
time += clock.getDelta();
plane.rotation.x = Math.sin(time) * THREE.Math.degToRad(10);
plane.rotation.y = time * 0.125;
renderer.render(scene, camera);
}