如何在Three.js场景中添加顶点/三角面计数与三轴辅助图例?
在Three.js中实现顶点/三角面统计与三轴辅助图例
一、三轴辅助图例(自带实现)
Three.js内置了现成的AxesHelper工具,直接调用就能生成三轴辅助线:
- 创建辅助对象:
const axesHelper = new THREE.AxesHelper(5);(参数是轴的长度,可根据场景尺寸调整) - 添加到场景:
scene.add(axesHelper); - 可选优化:如果想让辅助线始终朝向相机(固定在视野内),可以在渲染循环里添加
axesHelper.lookAt(camera.position);
二、顶点/三角面数量统计与显示
1. 核心统计逻辑
需要遍历场景内所有网格对象,累加顶点和三角面的数量:
function calculateSceneStats(scene) { let totalVertices = 0; let totalFaces = 0; scene.traverse((obj) => { if (obj.isMesh && obj.geometry) { const geo = obj.geometry; // 统计顶点数 totalVertices += geo.attributes.position?.count || 0; // 统计三角面数:有索引用索引长度/3,无索引用顶点数/3 const indexTotal = geo.index?.count || geo.attributes.position?.count || 0; totalFaces += Math.floor(indexTotal / 3); } }); return { totalVertices, totalFaces }; }
2. 屏幕固定显示(DOM元素方案)
最简便的方式是创建一个固定定位的DOM面板,在渲染循环里更新数据:
<!-- 先在HTML里加个容器 --> <div id="stats-panel" style="position: fixed; top: 10px; left: 10px; background: rgba(0,0,0,0.7); color: #fff; padding: 8px; font-family: monospace; font-size: 14px;"></div>
const statsPanel = document.getElementById('stats-panel'); // 渲染循环里更新内容 function animate() { requestAnimationFrame(animate); const { totalVertices, totalFaces } = calculateSceneStats(scene); statsPanel.innerHTML = ` 顶点数: ${totalVertices.toLocaleString()}<br> 三角面数: ${totalFaces.toLocaleString()} `; renderer.render(scene, camera); } animate();
3. 3D空间内显示(CSS2DObject方案)
如果想让统计面板作为3D场景的一部分(比如贴在某个模型旁),可以用CSS2DObject:
// 先导入CSS2D相关模块(Three.js自带) import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js'; // 创建统计面板DOM const statsDiv = document.createElement('div'); statsDiv.style.background = 'rgba(0,0,0,0.7)'; statsDiv.style.color = '#fff'; statsDiv.style.padding = '4px 8px'; statsDiv.style.fontFamily = 'monospace'; const statsObj = new CSS2DObject(statsDiv); statsObj.position.set(2, 2, 2); // 设置在3D空间中的位置 scene.add(statsObj); // 初始化CSS2D渲染器 const cssRenderer = new CSS2DRenderer(); cssRenderer.setSize(window.innerWidth, window.innerHeight); cssRenderer.domElement.style.position = 'absolute'; cssRenderer.domElement.style.top = '0'; document.body.appendChild(cssRenderer.domElement); // 渲染循环同时处理3D场景和CSS2D内容 function animate() { requestAnimationFrame(animate); const { totalVertices, totalFaces } = calculateSceneStats(scene); statsDiv.innerHTML = `顶点数: ${totalVertices}<br>三角面数: ${totalFaces}`; renderer.render(scene, camera); cssRenderer.render(scene, camera); } animate();
三、注意事项
- 如果场景有动态加载的模型,统计函数会自动遍历到新添加的网格;
- 合并后的几何体只会统计合并后的总数量,无法拆分到单个模型;
- 对性能敏感的场景,可以不用每帧统计,比如每隔10帧更新一次数据。
内容的提问来源于stack exchange,提问作者ashemez
相关产品推荐
相关产品推荐

