在做 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);

被折叠的 条评论
为什么被折叠?



