Three.js如何实现点击按钮动态修改InstancedMesh实例的随机颜色
问题根因
- 你使用的
MeshLambertMaterial默认未开启顶点颜色支持,无法识别InstancedMesh的实例颜色数据 - 你没有在初始化阶段为InstancedMesh的实例设置初始颜色,导致
instanceColor缓冲区没有被创建,后续调用setColorAt修改不会生效
修正方案
你需要调整两处初始化逻辑,点击事件的修改逻辑本身是正确的:
- 初始化材质时添加
vertexColors: true配置 - 实例化InstancedMesh后,先为所有实例设置初始的矩阵和颜色,确保缓冲区被正常初始化
修正后完整可运行代码
let instancesCount = 10; let matrix = new THREE.Matrix4(); let geometry = new THREE.BoxBufferGeometry(1, 1, 1); // 改动点:开启顶点颜色支持 let material = new THREE.MeshLambertMaterial({ vertexColors: true }); let mesh = new THREE.InstancedMesh(geometry, material, instancesCount); scene.add(mesh); // 新增:初始化所有实例的位置和颜色,保证缓冲区创建 for (let i = 0; i < instancesCount; i++) { // 这里可以自定义初始位置,避免实例重叠 matrix.setPosition(i * 1.5, 0, 0); mesh.setMatrixAt(i, matrix); mesh.setColorAt(i, new THREE.Color(0xffffff * Math.random())); } mesh.instanceMatrix.needsUpdate = true; mesh.instanceColor.needsUpdate = true; const clickHandler = (e) => { let max = instancesCount-1; let min = 0; let index = Math.floor(Math.random() * (max - min + 1) + min); // 补充+1避免永远取不到max值 // 如果不需要修改实例位置,下面三行矩阵相关代码可以直接删除 let x = Math.floor(Math.random() * (max - min + 1) + min); let y = Math.floor(Math.random() * (max - min + 1) + min); let z = Math.floor(Math.random() * (max - min + 1) + 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,会导致永远取不到最大值instancesCount-1,修正后随机取值范围是正确的。
内容的提问来源于stack exchange,提问作者jorgeb
相关产品推荐
相关产品推荐

