THREE.js使用raycaster实现悬停高亮立方体面时涂色不全怎么办
问题根因
Three.js 内置的BoxGeometry每个四边形面由两个独立的三角面拼接构成,Raycaster返回的命中face仅为构成该四边形面的其中一个三角面。你当前仅修改了命中的单个三角面的3个顶点颜色,同属一个四边形的另一个三角面顶点颜色未更新,因此会出现涂色不全的问题。
解决方案
按以下步骤修改代码即可实现完整面高亮:
- 先根据命中三角面的索引,计算出它所属的四边形面,再找到同组的另一个三角面:每个四边形面对应两个连续的三角面索引,将命中的
faceIndex整除2得到四边形面编号,对应两个三角面索引为面编号*2和面编号*2 +1 - 同时更新两个三角面的所有顶点颜色
- 确保几何体初始化时已添加顶点颜色属性,且材质开启了
vertexColors: true
修改后的核心代码示例
// 先获取命中的三角面索引 const faceIndex = intersected.faceIndex; // 计算所属的四边形面编号 const quadIndex = Math.floor(faceIndex / 2); // 拿到该四边形面对应的两个三角面的所有顶点索引 const geometry = intersected.object.geometry; const indexAttribute = geometry.getIndex(); const tri1A = indexAttribute.getX(quadIndex * 2 * 3 + 0); const tri1B = indexAttribute.getX(quadIndex * 2 * 3 + 1); const tri1C = indexAttribute.getX(quadIndex * 2 * 3 + 2); const tri2A = indexAttribute.getX(quadIndex * 2 * 3 + 3); const tri2B = indexAttribute.getX(quadIndex * 2 * 3 + 4); const tri2C = indexAttribute.getX(quadIndex * 2 * 3 + 5); // 给所有6个顶点设置高亮颜色 const colorAttribute = geometry.getAttribute('color'); const {r, g, b} = color; // 你定义的高亮颜色 colorAttribute.setXYZ(tri1A, r, g, b); colorAttribute.setXYZ(tri1B, r, g, b); colorAttribute.setXYZ(tri1C, r, g, b); colorAttribute.setXYZ(tri2A, r, g, b); colorAttribute.setXYZ(tri2B, r, g, b); colorAttribute.setXYZ(tri2C, r, g, b); colorAttribute.needsUpdate = true;
额外注意项
初始化立方体几何体时需要手动生成顶点颜色属性,代码参考:
const geometry = new THREE.BoxGeometry(1,1,1); const defaultColor = new THREE.Color(0xffffff); // 默认基础色 const colors = []; for(let i = 0; i < geometry.getAttribute('position').count; i++){ colors.push(defaultColor.r, defaultColor.g, defaultColor.b); } geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); const material = new THREE.MeshBasicMaterial({vertexColors: true}); const cube = new THREE.Mesh(geometry, material);
内容的提问来源于stack exchange,提问作者Front user32
相关产品推荐
相关产品推荐

