Three.js 中如何给 3D 模型添加文字标签?
在做 3D 可视化项目时,我们经常需要给场景中的物体、房间、设备等加上文字说明,比如:
房间号(101、102…)
设备标签(空调、电梯、传感器)
人员名字或状态
问题是:Three.js 本身不能直接显示文字。
我们需要一个办法,把文字“画”出来,再贴到 3D 世界里。
本文就带你实现:用 Canvas 生成文字 → 转换为纹理 → 在 Three.js 中作为标签展示。
🔹 为什么不用 HTML 直接写?
Three.js 有两种常见方式做标签:
HTML + CSS2DRenderer
直接用 DOM 元素 (
<div>
) 作为标签,叠加在 3D 场景上优点:样式好写,和写网页差不多
缺点:标签不是真正的 3D 对象,旋转时可能不跟随场景
Canvas 生成纹理 → Sprite (本文讲的方式)
用 Canvas 画一个文字框(可带背景、边框、圆角)
转换为 Three.js 纹理 → 贴到
Sprite
上优点:标签是真正的 3D 元素,跟随相机缩放、旋转
缺点:需要写点 Canvas 绘图代码
所以,当你需要“标签和模型在同一个 3D 世界里”时,Canvas 方案更合适。
🔹 实现思路
在 Canvas 上画一个“圆角矩形 + 文本”的小图片
把 Canvas 转换为
THREE.CanvasTexture
用
THREE.SpriteMaterial
包装成材质创建
THREE.Sprite
并放到场景中调整位置和缩放
🔹 代码实现
1. 创建一个文字标签
function createBoxLabel(text, options = {}) {const {color = "white", // 文字颜色fontSize = 28, // 字体大小bgColor = "black", // 背景颜色borderColor = "white", // 边框颜色borderWidth = 2, // 边框宽度borderRadius = 8, // 圆角半径padding = 10 // 内边距} = options;// 创建画布const canvas = document.createElement("canvas");const context = canvas.getContext("2d");canvas.width = 412;canvas.height = 156;// 绘制圆角矩形背景function roundRect(ctx, x, y, w, h, r) {ctx.beginPath();ctx.moveTo(x + r, y);ctx.lineTo(x + w - r, y);ctx.quadraticCurveTo(x + w, y, x + w, y + r);ctx.lineTo(x + w, y + h - r);ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);ctx.lineTo(x + r, y + h);ctx.quadraticCurveTo(x, y + h, x, y + h - r);ctx.lineTo(x, y + r);ctx.quadraticCurveTo(x, y, x + r, y);ctx.closePath();ctx.fillStyle = bgColor;ctx.fill();ctx.lineWidth = borderWidth;ctx.strokeStyle = borderColor;ctx.stroke();}roundRect(context, 0, 0, canvas.width, canvas.height, borderRadius);// 写文字context.fillStyle = color;context.font = `${fontSize}px Arial`;context.textAlign = "center";context.textBaseline = "middle";context.fillText(text, canvas.width / 2, canvas.height / 2);// 转换为 Three.js 纹理const texture = new THREE.CanvasTexture(canvas);const material = new THREE.SpriteMaterial({ map: texture, transparent: true });const sprite = new THREE.Sprite(material);// 缩放到合适大小sprite.scale.set(1.5, 0.75, 1);return sprite; }
2. 添加到场景
function addLabelAtPosition(text, x, y, z) {const label = createBoxLabel(text, {color: "white",bgColor: "black",borderColor: "#007bff"});label.position.set(x, y, z);scene.add(label);return label; }// 示例:在 3D 场景中某个位置加标签 addLabelAtPosition("101 房间", 0.1, 0.2, -3.2);