Reputation: 11
I'm trying to make a basic voxel viewer in three.js. The voxels should be either visible or invisible depending on whether the corresponding cell in an array is 0 or 1.
The voxels display perfectly when I set the opacity to 1 or 0, but when I try and set the directly from the voxels
array, they all turn invisible.
Can someone please give me a hand?
https://codepen.io/jjough/pen/VxMgOb?editors=0010
// the cubes should be visible if the
// corresponding array cell is 1.
var voxels = [
[
[0., 0., 1., 0., 0.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 0., 1.],
[1., 1., 0., 0., 1.]
],
[
[0., 0., 1., 0., 0.],
[1., 1., 1., 1., 1.],
[1., 0., 0., 0., 1.],
[1., 1., 1., 0., 1.],
[0., 1., 0., 0., 1.]
]
]
// Create a scene which will hold all our meshes to be rendered
var scene = new THREE.Scene();
// Create and position a camera
var camera = new THREE.PerspectiveCamera(
60, // Field of view
window.innerWidth / window.innerHeight, // Aspect ratio
0.1, // Near clipping pane
1000 // Far clipping pane
);
// Reposition the camera
camera.position.set(5, 5, 0);
// Point the camera at a given coordinate
camera.lookAt(new THREE.Vector3(0, 0, 0));
// Create a renderer
var renderer = new THREE.WebGLRenderer({
antialias: true
});
// Size should be the same as the window
renderer.setSize(window.innerWidth, window.innerHeight);
// Set a near white clear color (default is black)
renderer.setClearColor(0xfff6e6);
// Append to the document
document.body.appendChild(renderer.domElement);
// A mesh is created from the geometry and material, then added to the scene
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(5, 5, 5, 5),
new THREE.MeshBasicMaterial({
color: 0x393839,
wireframe: true,
opacity: 0.2,
transparent: true
})
);
plane.rotateX(Math.PI / 2);
scene.add(plane);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshStandardMaterial({
color: 0x00ff00,
flatShading: true, // default is THREE.SmoothShading
metalness: 0,
roughness: 1,
vertexColors: THREE.VertexColors,
opacity: 0.5,
transparent: true,
});
var voxel_objects = [];
for (var h = 0; h < 5; h += 1) {
for (var v = 0; v < 5; v += 1) {
cube = new THREE.Mesh(geometry, material);
voxel_objects.push(cube);
cube.position.set(h - (5 - 1) / 2, 0.5, v - (5 - 1) / 2);
cube.visible = !!voxels[0][h][v];
scene.add(cube);
}
}
function update_voxels(frame) {
for (var h = 0; h < 5; h += 1) {
for (var v = 0; v < 5; v += 1) {
cube = voxel_objects[h * 5 + v];
cube.visible = !!voxels[frame][h][v];
}
}
}
var ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(25, 50, 25);
scene.add(pointLight);
var step = 0;
var gui_controls = new function() {
this.rotationSpeed = 0.5;
this.bouncingSpeed = 0.03;
};
var gui = new dat.GUI();
gui.add(gui_controls, 'rotationSpeed', 0, 1);
gui.add(gui_controls, 'bouncingSpeed', 0, 0.5);
render();
var count = 0;
function render() {
//cube.material.opacity = gui_controls.rotationSpeed;
//cube.material.opacity.needsUpdate = true;
// render using requestAnimationFrame
requestAnimationFrame(render);
count += 1;
frame = Math.floor(count / 60);
if (count == 120) {
count = 0
};
if (count%60 -1== 0){console.log(frame); update_voxels(frame)};
renderer.render(scene, camera);
}
// Add an orbit control which allows us to move around the scene. See the three.js example for more details
// https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/OrbitControls.
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', function() {
renderer.render(scene, camera);
}); // add this only if there is no animation loop (requestAnimationFrame)
body {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.min.js"></script>
Upvotes: 0
Views: 191
Reputation: 11
Thanks to @prisoner849
: needed to cast to Boolean. cube.visible = !!voxels[h][v];
Upvotes: 1