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

如何定位射线检测的fragmentMesh实例并为其设置独立材质

实例化Mesh射线检测与独立材质设置解决方案

1. 识别射线检测击中的实例ID

当射线检测命中InstancedMesh的某个实例时,返回的Intersection对象会携带instanceId属性,这个值就是击中实例的索引。你可以直接从检测结果中获取:

const raycaster = viewer.raycaster;
const intersect: Intersection | null = raycaster.castRay([...this.components.meshes]);
if (intersect) {
  // 获取击中的具体实例ID
  const targetInstanceId = intersect.instanceId;
  // 这里可以用这个ID做后续区分逻辑
}

注意:只有检测对象是InstancedMesh时,instanceId才会存在,普通Mesh没有该属性。

2. 给指定实例设置自定义材质

InstancedMesh默认共享同一组几何和材质,无法直接单独修改某个实例的材质,推荐两种可行方案:

方案一:拆分目标实例为独立Mesh

把需要单独设置材质的实例从InstancedMesh中提取出来,转为普通Mesh:

if (intersect && intersect.object instanceof InstancedMesh) {
  const instancedMesh = intersect.object as InstancedMesh;
  const instanceId = intersect.instanceId;
  
  // 创建新Mesh,复用原几何结构
  const customMaterial = new MeshStandardMaterial({ color: 0xff0000 }); // 自定义材质
  const singleMesh = new Mesh(instancedMesh.geometry, customMaterial);
  
  // 获取目标实例的矩阵并应用到新Mesh
  const matrix = new Matrix4();
  instancedMesh.getMatrixAt(instanceId, matrix);
  singleMesh.applyMatrix4(matrix);
  
  // 从原InstancedMesh中移除该实例
  instancedMesh.removeMatrixAt(instanceId);
  instancedMesh.instanceMatrix.needsUpdate = true;
  
  // 将新Mesh添加到场景中
  instancedMesh.parent?.add(singleMesh);
}

这种方法适合需要长期单独修改的实例,缺点是会增加场景中的Mesh数量。

方案二:用着色器材质通过实例ID控制属性

如果不想拆分实例,可以自定义着色器材质,通过实例ID传递材质参数(如颜色、纹理):

  1. 给InstancedMesh添加自定义实例属性,存储每个实例的材质配置:
const instancedMesh = intersect.object as InstancedMesh;
const targetInstanceId = intersect.instanceId;

// 给每个实例存储颜色数据,这里仅修改目标实例为红色
const colors = new Float32Array(instancedMesh.count * 3);
colors[targetInstanceId * 3] = 1;
colors[targetInstanceId * 3 + 1] = 0;
colors[targetInstanceId * 3 + 2] = 0;

// 添加实例属性到InstancedMesh
instancedMesh.setAttribute('instanceColor', new InstancedBufferAttribute(colors, 3));
  1. 编写自定义着色器:
// 顶点着色器
attribute vec3 instanceColor;
varying vec3 vInstanceColor;

void main() {
  vInstanceColor = instanceColor;
  // 保留原顶点着色器的逻辑(如矩阵变换、UV计算等)
  vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
  gl_Position = projectionMatrix * modelViewPosition;
}

// 片元着色器
varying vec3 vInstanceColor;

void main() {
  gl_FragColor = vec4(vInstanceColor, 1.0);
  // 可结合原片元逻辑(如光照、纹理采样)
}
  1. 将InstancedMesh的材质替换为该自定义着色器材质,即可通过instanceColor单独控制目标实例的颜色,同理可扩展到其他材质属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:56:24