PROWAREtech
ThreeJS: Create a Cube Array
How to create a cube grid array using THREE.js.
In this function, specify the size of the grid (rounds to a value with a power of three) the cube size and the distance between each cube.
var createCubeGrid = function (gridSize, cubeSize, gap) {
var x = 0, y = 0, z = 0, rows, cols, colors = [0x666666, 0x999999, 0xCCCCCC], group = new THREE.Group();
gap = Math.abs(gap);
gridSize = Math.pow(gridSize, 1 / 3);
if (gridSize % 1 != 0) {
gridSize = Math.round(gridSize);
}
rows = cols = gridSize;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
for (var depth = 0; depth < rows; depth++) {
var position = cubeSize / 2 * rows / 2 + gap;
x = position * row;
y = position * col;
z = position * depth;
var num = (row + col + depth) % 3;
var mesh = new THREE.Mesh(new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize), new THREE.MeshPhongMaterial({ color: colors[num] }));
mesh.receiveShadow = mesh.castShadow = true; // NOTE: optional
mesh.position.set(x, y, z);
group.add(mesh);
}
}
}
group.position.set(x / -2, y / -2, z / -2); // NOTE: center the group of cubes
var grid = new THREE.Group();
grid.add(group);
return grid;
};
Here is a working example of the above function:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shadows</title>
<style>
canvas {
display: block;
width: 300px;
height: 300px;
}
</style>
</head>
<body>
<canvas></canvas>
<script src="/js/three.min.js"></script>
<script type="text/javascript">
(function () {
var createCubeGrid = function (gridSize, cubeSize, gap) {
var x = 0, y = 0, z = 0, rows, cols, colors = [0x666666, 0x999999, 0xCCCCCC], group = new THREE.Group();
gap = Math.abs(gap);
gridSize = Math.pow(gridSize, 1 / 3);
if (gridSize % 1 != 0) {
gridSize = Math.round(gridSize);
}
rows = cols = gridSize;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
for (var depth = 0; depth < rows; depth++) {
var position = cubeSize / 2 * rows / 2 + gap;
x = position * row;
y = position * col;
z = position * depth;
var num = (row + col + depth) % 3;
var mesh = new THREE.Mesh(new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize), new THREE.MeshPhongMaterial({ color: colors[num] }));
mesh.receiveShadow = mesh.castShadow = true;
mesh.position.set(x, y, z);
group.add(mesh);
}
}
}
group.position.set(x / -2, y / -2, z / -2); // NOTE: center the group of cubes
var grid = new THREE.Group();
grid.add(group);
return grid;
};
var canvas = document.getElementsByTagName("canvas")[0];
// NOTE: create the scene to place objects in
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x6699CC); // NOTE: make the background blue for the sky
scene.matrixWorldAutoUpdate = true;
// NOTE: the width and height of the canvas
var size = {
width: canvas.offsetWidth,
height: canvas.offsetHeight
};
var cameraNear = 1, cameraFar = 5000;
// NOTE: create the camera with 53 degree field of view; this is how the scene is viewed by the user
var camera = new THREE.PerspectiveCamera(53, size.width / size.height, cameraNear, cameraFar);
// NOTE: position the camera in space a bit
camera.position.z = 3;
var renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
});
renderer.shadowMap.enabled = true; // NOTE: must enable shadows on the renderer
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(size.width, size.height);
renderer.render(scene, camera);
var light = new THREE.DirectionalLight(0xffffff, 1.5);
light.position.set(2, 2, 2);
light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
light.shadow.camera.near = cameraNear;
light.shadow.camera.far = cameraFar;
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, .3)); // NOTE: add a touch of ambient light
var grid = createCubeGrid(64, 0.2, 0.2);
scene.add(grid);
// NOTE: MUST HAVE AN ANIMATE FUNCTION
var animate = function () {
var frame = Math.PI / 192;
grid.rotation.x += frame;
grid.rotation.y += frame;
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
animate();
})();
</script>
</body>
</html>
Comment