jjough
jjough

Reputation: 11

Threejs change voxel opacity from array

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

Answers (1)

jjough
jjough

Reputation: 11

Thanks to @prisoner849 : needed to cast to Boolean. cube.visible = !!voxels[h][v];

Upvotes: 1

Related Questions