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>
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 indices = [];
for (let i = 0; i < y + 1;...
CSS
body {
overflow: hidden;
margin: 0;
}
JavaScript
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-3, 2, 1).setLength(20);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x808080);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, .5);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, .5));
var boxGeometry = new THREE.BoxBufferGeometry(10, 3, 3, 10, 5, 4);
boxGeometry.attributes.positionStart = boxGeometry.attributes.position.clone();
var gridGeometry = GridBoxGeometry(boxGeometry, false);
var box = new THREE.Mesh(boxGeometry, new THREE.MeshStandardMaterial({
color: 0x999999
}));
box.position.z = -3;
scene.add(box);
var grid = new THREE.LineSegments(gridGeometry, new THREE.LineBasicMaterial({
color: "aqua"
}));
grid.position.z = -3;
scene.add(grid);
var boxGeometry2 = new THREE.BoxBufferGeometry(10, 3, 3, 10, 5, 4);
boxGeometry2.attributes.positionStart = boxGeometry2.attributes.position.clone();
var box2 = new THREE.Mesh(boxGeometry2, box.material.clone());
box2.position.z = 3;
scene.add(box2);
var gridGeometry2 = GridBoxGeometry(boxGeometry2, true);
var grid2 = new THREE.LineSegments(gridGeometry2, grid.material.clone());
grid2.position.z = 3;
scene.add(grid2);
var position = boxGeometry.attributes.position;
var positionStart = boxGeometry.attributes.positionStart;
var position2 = boxGeometry2.attributes.position;
var positionStart2 = boxGeometry2.attributes.positionStart;
var clock = new THREE.Clock();
var time = 0;
render();
function render() {
requestAnimationFrame(render);
time += clock.getDelta();
for (let i = 0; i < position.count; i++) {
position.setY(i, positionStart.getY(i) + Math.sin(position.getX(i) * .5 + time) * .25);
...