Динамически изменяйте цвет экземпляра сетки в Three.js

#three.js

Вопрос:

Я пытаюсь войти Three.js чтобы случайным образом изменить цвет экземпляра instancedMesh на событии нажатия кнопки, без успеха.

 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;
}
 

Ответ №1:

Добавьте matrix.makeScale(1, 1, 1) прямо перед 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> 

Комментарии:

1. Спасибо, чувак, как масштабирование влияет на цвет экземпляра?