Reputation: 23
I am trying in Three.js to randomly change the color of an instance of an instancedMesh on a button click event with no success.
let instancesCount = 10;
let matrix = new THREE.Matrix4();
let geometry = new THREE.BoxBufferGeometry(1, 1, 1);
let material = new THREE.MeshLambertMaterial();
let mesh = new THREE.InstancedMesh(geometry, material, instancesCount);
scene.add(mesh);
const clickHandler = (e) => {
let max = instancesCount-1;
let min = 0;
let index = Math.floor(Math.random() * (max - min) + min);
let x = Math.floor(Math.random() * (max - min) + min);
let y = Math.floor(Math.random() * (max - min) + min);
let z = Math.floor(Math.random() * (max - min) + min);
matrix.setPosition(x, y, z);
mesh.setMatrixAt(index, matrix);
mesh.setColorAt(index, new THREE.Color(0xffffff * Math.random()));
mesh.instanceMatrix.needsUpdate = true;
mesh.instanceColor.needsUpdate = true;
}
Upvotes: 1
Views: 2191
Reputation: 17586
Add matrix.makeScale(1, 1, 1)
right before matrix.setPosition(x, y, z)
:
body{
overflow: hidden;
margin: 0;
}
<button id="btn_rand" style="position: absolute;margin: 5px;">
PressMe
</button>
<script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
import {OrbitControls} from "https://threejs.org/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.setScalar(15);
let renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x202020);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
scene.add(new THREE.GridHelper(20, 20));
let instancesCount = 10;
let matrix = new THREE.Matrix4();
let color = new THREE.Color();
let geometry = new THREE.BoxBufferGeometry(1, 1, 1);
let material = new THREE.MeshLambertMaterial({color: "white"});
let mesh = new THREE.InstancedMesh(geometry, material, instancesCount);
new Array(10).fill(0).forEach((c, i) => {mesh.setColorAt(i, color.set(0xffffff))});
scene.add(mesh);
btn_rand.addEventListener("click", clickHandler);
function clickHandler (e) {
let max = instancesCount-1;
let min = 0;
let index = THREE.MathUtils.randInt(min, max);
let x = Math.floor(Math.random() * (max - min) + min);
let y = Math.floor(Math.random() * (max - min) + min);
let z = Math.floor(Math.random() * (max - min) + min);
matrix.makeScale(1, 1, 1);
matrix.setPosition(x, y, z);
mesh.setMatrixAt(index, matrix);
mesh.setColorAt(index, color.set(0xffffff * Math.random()));
mesh.instanceMatrix.needsUpdate = true;
mesh.instanceColor.needsUpdate = true;
}
renderer.setAnimationLoop( _ => {
renderer.render(scene, camera);
})
</script>
Upvotes: 3