目录
[2. 如果是给 Mesh 做分割标注](#2. 如果是给 Mesh 做分割标注)
[Label Studio 官方网站](#Label Studio 官方网站)
[3. 如果是 Web 端编辑 GLB](#3. 如果是 Web 端编辑 GLB)
[4. 如果是 AI 资产生产线](#4. 如果是 AI 资产生产线)
[Three.js + 自定义标注](#Three.js + 自定义标注)
[5. 如果要类似 LabelMe 的 3D 标注](#5. 如果要类似 LabelMe 的 3D 标注)
[6. 如果你的目标是训练"动物部件识别"](#6. 如果你的目标是训练“动物部件识别”)
three-bvh-csg
点选功能:
http://localhost:5173/simple.html

连接件
http://localhost:5173/coplanar.html

挖空
bash
http://localhost:5173/geometry.html
加载glb
simple.js
javascript
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
import { Brush, Evaluator, ADDITION } from 'three-bvh-csg';
// renderer / scene / camera
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(3, 3, 3);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// ========== 关键:添加控制器 ==========
// 1. OrbitControls - 控制相机(旋转/缩放/平移场景)
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 惯性效果
controls.dampingFactor = 0.05;
controls.zoomSpeed = 1.2;
controls.rotateSpeed = 1.0;
controls.enableZoom = true;
controls.enablePan = true;
// 2. TransformControls - 控制物体(移动/旋转/缩放模型)
const transformControls = new TransformControls(camera, renderer.domElement);
transformControls.addEventListener('dragging-changed', (event) => {
// 拖动物体时禁用相机控制器
controls.enabled = !event.value;
});
scene.add(transformControls.getHelper());
// 辅助工具
const axesHelper = new THREE.AxesHelper(2);
scene.add(axesHelper);
const gridHelper = new THREE.GridHelper(10, 20, 0x888888, 0x444444);
scene.add(gridHelper);
// 灯光
scene.add(new THREE.AmbientLight(0xffffff, 0.6));
const dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(5, 5, 5);
dirLight.castShadow = true;
scene.add(dirLight);
scene.add(dirLight.target);
const backLight = new THREE.DirectionalLight(0xffffff, 0.5);
backLight.position.set(-2, 1, -3);
scene.add(backLight);
// 键盘快捷键:W=移动,E=旋转,R=缩放
window.addEventListener('keydown', (e) => {
switch (e.code) {
case 'KeyW': transformControls.setMode('translate'); break;
case 'KeyE': transformControls.setMode('rotate'); break;
case 'KeyR': transformControls.setMode('scale'); break;
}
});
const evaluator = new Evaluator();
const loader = new GLTFLoader();
let resultMesh = null;
// 加载 GLB
loader.load(
'./niu.glb',
(gltf) => {
const model = gltf.scene;
// 开启阴影
model.traverse((child) => {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
scene.add(model);
// 将 TransformControls 绑定到模型上
transformControls.attach(model);
// 调整相机位置以适应模型
const box = new THREE.Box3().setFromObject(model);
const center = box.getCenter(new THREE.Vector3());
const size = box.getSize(new THREE.Vector3());
const maxDim = Math.max(size.x, size.y, size.z);
camera.position.set(center.x + maxDim, center.y + maxDim * 0.8, center.z + maxDim * 1.5);
camera.lookAt(center);
controls.target.copy(center);
console.log("模型加载成功");
},
(xhr) => {
console.log(Math.round(xhr.loaded / xhr.total * 100) + '%');
},
(error) => {
console.error('加载失败:', error);
}
);
// 动画循环
function animate() {
requestAnimationFrame(animate);
// 更新控制器(支持惯性效果)
controls.update();
renderer.render(scene, camera);
}
animate();
three-gltf-viewer
bash
npm install
npm run dev
bash
https://github.com/donmccurdy/three-gltf-viewer
2. 如果是给 Mesh 做分割标注
例如:
狗模型
↓
点击耳朵
↓
标记为 Ear
比较成熟的是:
Label Studio 官方网站
支持自定义前端。
很多团队会:
Three.js
+
Label Studio
自己做 Mesh 面选取。
3. 如果是 Web 端编辑 GLB
最成熟的是:
Spline
支持:
- 导入 GLB
- 编辑材质
- 添加灯光
- 标注热点(Hotspot)
例如:
点击耳朵
显示:
Lion Ear
非常适合产品展示。
4. 如果是 AI 资产生产线
你这种场景:
AIGC
↓
TRELLIS
↓
GLB
↓
人工审核
其实最常见的是:
Three.js + 自定义标注
实现:
点击 Mesh
↓
记录 Face ID
↓
记录 Label
↓
保存 JSON
例如:
{
"tail": [123,124,125],
"ear": [456,457,458]
}
很多 3D 数据集都是这么做出来的。
5. 如果要类似 LabelMe 的 3D 标注
推荐看看:
Supervisely
支持:
- 点云
- Mesh
- 3D Cuboid
- 团队协作
属于目前工业界比较成熟的方案之一。
6. 如果你的目标是训练"动物部件识别"
例如:
狮子
↓
头部
鬃毛
尾巴
四肢
我会建议直接基于:
- Three.js
- React Three Fiber
- GLTFLoader
开发一个轻量标注系统。
功能只需要:
上传GLB
↓
点击区域
↓
输入标签
↓
保存JSON
两三周就能做出来,而且比 CVAT、Supervisely 更贴合你的动物手办场景。
所以我想确认一下,你说的 3D标注 是:
- 给整个模型分类(狮子、老虎、小狗)?
- 给模型部件打标签(耳朵、尾巴、腿)?
- 给 Mesh 面片做语义分割标注?
- 给 3D 检测框/Cuboid 标注?
这几种工具路线差别很大。