You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为PlaneBufferGeometry的各分段设置或更新不同颜色?

实现点击平面网格分段更新颜色的方案

嘿,要实现点击平面的某部分并更新对应网格分段的颜色,咱们可以通过射线检测(Raycaster) + BufferGeometry颜色属性来搞定,步骤很清晰,一起来看:

1. 调整几何体与材质,启用顶点颜色

因为你用的是PlaneBufferGeometry(缓冲区几何体,性能更好),咱们需要给它添加顶点颜色属性,同时让材质支持顶点颜色:

// 创建平面缓冲区几何体,参数:宽度、高度、横向分段数、纵向分段数
var geometry = new THREE.PlaneBufferGeometry(5, 20, 32, 32);

// 初始化颜色数组:每个顶点对应RGB三个值,初始全为红色(和你原来的颜色一致)
const vertexCount = geometry.attributes.position.count;
const colors = new Float32Array(vertexCount * 3);
const defaultColor = new THREE.Color(0xCC0000);

for (let i = 0; i < vertexCount; i++) {
  const offset = i * 3;
  colors[offset] = defaultColor.r;
  colors[offset + 1] = defaultColor.g;
  colors[offset + 2] = defaultColor.b;
}

// 将颜色数组作为属性添加到几何体
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));

// 创建材质,开启顶点颜色(这样顶点颜色会覆盖基础颜色)
var material = new THREE.MeshBasicMaterial({ 
  color: 0xCC0000, 
  side: THREE.DoubleSide,
  vertexColors: THREE.VertexColors 
});

var plane = new THREE.Mesh(geometry, material);
scene.add(plane);

2. 实现点击检测与颜色更新

接下来需要监听鼠标点击事件,用Raycaster检测点击的平面区域,然后修改对应分段的顶点颜色:

// 初始化射线检测工具和鼠标坐标对象
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

// 监听窗口点击事件
window.addEventListener('click', handlePlaneClick);

function handlePlaneClick(event) {
  // 将浏览器鼠标坐标转换为Three.js标准坐标(范围:-1 到 1)
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  // 更新射线的起点(相机位置)和方向(鼠标指向的方向)
  raycaster.setFromCamera(mouse, camera); // 这里的camera是你场景中的相机对象

  // 检测射线与平面的交点
  const intersects = raycaster.intersectObject(plane);

  if (intersects.length > 0) {
    // 获取第一个交点(最靠近相机的那个)
    const intersect = intersects[0];
    // 交点对应的三角形面(BufferGeometry会临时生成Face3对象,包含顶点索引a/b/c)
    const face = intersect.face;
    // 获取几何体的颜色属性
    const colorAttribute = plane.geometry.attributes.color;
    // 定义点击后要设置的新颜色(这里用绿色举例)
    const newColor = new THREE.Color(0x00FF00);

    // 修改当前三角形三个顶点的颜色
    colorAttribute.setXYZ(face.a, newColor.r, newColor.g, newColor.b);
    colorAttribute.setXYZ(face.b, newColor.r, newColor.g, newColor.b);
    colorAttribute.setXYZ(face.c, newColor.r, newColor.g, newColor.b);

    // 如果想让整个四边形分段(两个三角形)都变色,还可以根据顶点索引规律找到相邻三角形并修改
    // 比如32x32分段的平面,横向有33个顶点,纵向33个,可通过索引计算找到同属一个四边形的其他顶点

    // 标记颜色属性需要更新,Three.js才会渲染新颜色
    colorAttribute.needsUpdate = true;
  }
}

3. 额外说明

  • 不管你用的是PerspectiveCamera还是OrthographicCamera,上述射线检测逻辑都适用,无需额外调整。
  • 如果你追求更精准的“四边形分段”变色,可以根据PlaneBufferGeometry的顶点索引规律,计算出当前三角形所属四边形的所有顶点,一次性修改它们的颜色。
  • 务必确保代码中的camera变量是你场景中实际使用的相机对象,否则射线检测会失效。

内容的提问来源于stack exchange,提问作者rockon1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:35:01