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

如何获取Three.js中InstancedMesh各实例的顶点位置?

获取Three.js InstancedMesh单个实例的顶点世界坐标

问题场景

已通过以下代码创建InstancedMesh及对应的dummy Object3D数组,实现了单个实例的独立操控,但无法像普通Mesh那样获取每个实例的顶点信息:

const parentGeometry = new THREE.BoxBufferGeometry( 10, 10, 10, 1, 1, 1 );
const instancedGeometry = new THREE.InstancedBufferGeometry();

const material = new THREE.MeshPhongMaterial( { color: 0xFF0000 } )

THREE.BufferGeometry.prototype.copy.call( instancedGeometry, parentGeometry );

var defaultTransform = new THREE.Matrix4().multiply( new THREE.Matrix4().makeScale( 1, 1, 1 ) )
instancedGeometry.applyMatrix4( defaultTransform );

instancedMeshes = new THREE.InstancedMesh( instancedGeometry, material, instanceCount );
instancedMeshes.instanceMatrix.setUsage( THREE.DynamicDrawUsage );

// 创建dummy数组用于单独控制每个实例
for ( let i = 0; i < instanceCount; i ++ ) {
    let dummy = new THREE.Object3D();
    dummyArray.push( dummy );
    dummyArray[i].position.copy( new THREE.Vector3( i*15-100,0,-100 ) );
    dummyArray[i].updateMatrix();
    instancedMeshes.setMatrixAt( i, dummyArray[i].matrix );
    instancedMeshes.instanceMatrix.needsUpdate = true;
}

scene.add( instancedMeshes );

普通Mesh的顶点获取代码对InstancedMesh无效(因每个实例无独立geometry属性):

// 普通Mesh可用,但InstancedMesh实例不适用
let meshVertices = meshArray[i].geometry.attributes["position"].array;
meshArray[i].updateMatrixWorld();
let mesh_top_left_vertices = meshArray[i].localToWorld( new THREE.Vector3( meshVertices[15], meshVertices[15 + 1], meshVertices[15 + 2] ) ) 

解决方案

InstancedMesh的所有实例共享同一个基础几何体,每个实例的变换信息存储在对应的dummy对象中。只需将基础几何体的局部顶点,通过对应实例的世界变换矩阵转换,即可得到该实例顶点的世界坐标:

实现步骤

  1. 获取基础几何体的顶点数据:可直接使用创建InstancedMesh时的parentGeometry,或从instancedMeshes.geometry中读取(两者顶点数据一致)。
  2. 更新实例的世界矩阵:确保dummy对象的变换是最新的。
  3. 转换顶点坐标:用实例的世界矩阵将基础几何体的局部顶点转换为世界坐标。

代码示例

// 获取基础几何体的顶点数组
const baseVertices = instancedMeshes.geometry.attributes.position.array;

// 处理第i个实例
const targetIndex = i; // 替换为你需要查询的实例索引
const dummy = dummyArray[targetIndex];

// 更新dummy的世界矩阵(确保包含父节点变换)
dummy.updateMatrixWorld();

// 取出基础几何体中目标局部顶点
const localVertex = new THREE.Vector3(
    baseVertices[15], 
    baseVertices[16], 
    baseVertices[17]
);

// 用实例的世界矩阵转换为世界坐标
const worldVertex = localVertex.applyMatrix4(dummy.matrixWorld);

console.log(`第${targetIndex}个实例的目标顶点世界坐标:`, worldVertex);

关键说明

  • InstancedMesh的核心优势是共享几何体与材质,减少Draw Call,因此每个实例没有独立的geometry属性,所有实例共用同一套顶点数据。
  • dummy对象的matrixWorld包含了该实例的所有变换(位置、旋转、缩放),是转换顶点坐标的关键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:55:20