如何在Three.js中加载同时包含三角形和孤立顶点的PLY网格
问题根源
该问题由PLYLoader的默认加载逻辑和Three.js索引几何体的渲染规则共同导致:
- 当PLY文件包含面数据时,
PLYLoader会为生成的BufferGeometry自动设置index属性,这个索引数组仅收录被面引用到的顶点ID - 渲染
THREE.Points时,如果几何体带有索引,只会渲染索引数组中列出的顶点,未被面引用的孤立顶点自然不会显示 toNonIndexed()方法无效是因为它只会基于现有索引生成非索引顶点,不会保留未被索引收录的原始顶点
可行解决方案
方案1:清空Points所用几何体的索引(最优推荐)
该方案性能损耗极低,不需要额外复制顶点数据,是目前最简便的实现方式:
const loader = new THREE.PLYLoader(); const baseGeometry = loader.parse(meshString); // 渲染三角形的Mesh直接使用带索引的原始几何体,节省显存 const mesh = new THREE.Mesh(baseGeometry, meshMaterial); scene.add(mesh); // 克隆原始几何体给Points使用,仅清空索引,不会重复复制顶点数据 const pointsGeometry = baseGeometry.clone(); pointsGeometry.index = null; const meshPoints = new THREE.Points(pointsGeometry, pointsMaterial); scene.add(meshPoints);
注意不要直接修改原始几何体的
index属性,否则用于渲染三角形的Mesh会失效,单独克隆一份给Points使用即可,克隆操作仅复制属性引用,几乎没有额外开销。
方案2:单独创建Points专属几何体
如果后续需要对网格和顶点做独立的变换操作,可以选择该方案实现数据完全隔离:
const baseGeometry = loader.parse(meshString); // 渲染网格用原始几何体 const mesh = new THREE.Mesh(baseGeometry, meshMaterial); scene.add(mesh); // 基于原始顶点属性单独创建顶点几何体 const pointsGeo = new THREE.BufferGeometry(); pointsGeo.setAttribute('position', baseGeometry.attributes.position); // 若存在颜色、法线等其他顶点属性,可按同样方式复制 if (baseGeometry.attributes.color) { pointsGeo.setAttribute('color', baseGeometry.attributes.color); } const points = new THREE.Points(pointsGeo, pointsMaterial); scene.add(points);
内容的提问来源于stack exchange,提问作者roberto
相关产品推荐
相关产品推荐

