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

如何从OBJLoader加载的Object3D创建BufferGeometry?

解决Object3D转BufferGeometry的问题

你踩了两个典型的Three.js新手坑——混淆了容器对象和几何体对象,以及没搞懂BufferGeometry和旧版Geometry的差异,咱们一个个说清楚:

1. 第一种方法报错的原因

OBJLoader加载完成返回的是Object3D(本质是一个可以包含多个Mesh的组容器),但BufferGeometry.fromGeometry()要求的参数是**THREE.Geometry类型的几何体对象**,你直接把整个Object3D传进去,方法自然找不到它需要的顶点/面数据,才会报Cannot read property '0' of undefined。

正确的操作是先从Object3D里取出真正的Mesh,再拿它的Geometry:

const loader = new THREE.OBJLoader();
loader.load('你的模型.obj', (object3d) => {
  // 遍历容器里的所有子对象,找到Mesh类型的元素
  object3d.traverse((child) => {
    if (child.isMesh) {
      // child.geometry才是你要的Geometry对象
      const bufferGeo = new THREE.BufferGeometry().fromGeometry(child.geometry);
      // 现在bufferGeo就是可用的BufferGeometry了
    }
  });
});

2. 为什么第二种方法里bgeometry.faces是undefined?

因为BufferGeometry根本没有faces属性!faces是旧版Geometry的专属属性,BufferGeometry用更高效的「顶点属性数组」和「索引数组」来存储数据:

  • 顶点坐标存在bufferGeo.attributes.position
  • 面的顶点索引存在bufferGeo.index(如果是索引化几何体)

如果想查看面的数量,你可以这样算:

const bufferGeo = new THREE.BufferGeometry();
bufferGeo.setFromObject(object3d); // 这个方法会自动合并Object3D下所有可见Mesh的几何体

// 查看总顶点数
console.log(bufferGeo.attributes.position.count);
// 查看索引总数(每个面对应3个索引)
if (bufferGeo.index) {
  const faceCount = bufferGeo.index.count / 3;
  console.log(`总面数:${faceCount}`);
} else {
  // 无索引的话,每3个顶点组成一个面
  const faceCount = bufferGeo.attributes.position.count / 3;
  console.log(`总面数:${faceCount}`);
}

另外补充:setFromObject()会自动合并模型里的所有Mesh,如果你需要逐个处理单个面,建议先单独取出每个Mesh的几何体再转BufferGeometry,避免合并后的数据不好拆分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:13:11