THREE.js/CSS2DRenderer代码正确但标签不可见的问题求助
Three.js CSS2D标签已存在但无法显示的问题
我尝试为Three.js中的3D模型添加名称标签,控制台日志能确认标签对象存在,但标签始终无法在屏幕上显示,调整z-index值也没有效果。以下是我的相关代码和已尝试的无效方案:
相关代码
index.html
<body> <canvas id="three-canvas"></canvas> </body>
main.css
body { overflow: hidden; margin: 0; } #three-canvas { position: fixed; left: 0; top: 0; } .label { color: #000000; background-color: #fde047; padding: 40px; /* font-family: sans-serif; */ font-size: 30px; z-index: 10 !important; }
main.js
/** Renderer */ const canvas = document.querySelector("#three-canvas"); const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; /** CSS2DRenderer */ const labelRenderer = new CSS2DRenderer(); labelRenderer.setSize(window.innerWidth, window.innerHeight); labelRenderer.domElement.style.position = "absolute"; labelRenderer.domElement.style.top = "0px"; canvas.appendChild(labelRenderer.domElement); /** Scene */ const scene = new THREE.Scene(); const gltfLoader = new GLTFLoader(); ... (Light and Camera) ... /** 🚩 Geometry */ const geometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); const material = new THREE.MeshPhongMaterial({ color: "hotpink", shininess: 5, side: THREE.DoubleSide, }); const test = new THREE.Mesh(geometry, material); test.position.set(1, 0.5, 1); scene.add(test); test.layers.enableAll(); const labelDiv = document.createElement("div"); labelDiv.className = "label"; labelDiv.textContent = "Label Text Here"; labelDiv.style.backgroundColor = "yellow"; const labelText = new CSS2DObject(labelDiv); labelText.position.set(1, 0, 0); labelText.center.set(0, 1); test.add(labelText); labelText.layers.set(0); /** play */ function draw() { renderer.setAnimationLoop(draw); renderer.render(scene, camera); labelRenderer.render(scene, camera); } /** Event */ window.addEventListener("resize", setSize); draw();
已尝试的无效方案
- 通过容器为GLTF模型添加标签,控制台打印标签存在但不可见:
export class Player { constructor(info) { this.moving = false; info.gltfLoader.load(info.modelSrc, (glb) => { glb.scene.traverse((child) => { if (child.isMesh) { child.castShadow = true; } }); this.modelMesh = glb.scene.children[0]; this.modelMesh.position.set(0, 0.3, 0); this.modelMesh.name = "player"; this.modelMesh.layers.enableAll(); const label = document.createElement("div"); label.className = "label"; label.textContent = "Label text here"; const labelObj = new CSS2DObject(label); labelObj.position.set(3, 3, 0); const container = new THREE.Object3D(); container.add(this.modelMesh); container.add(labelObj); container.position.copy(this.modelMesh.position); info.scene.add(container); this.actions = []; this.mixer = new AnimationMixer(this.modelMesh); this.actions[0] = this.mixer.clipAction(glb.animations[0]); this.actions[1] = this.mixer.clipAction(glb.animations[1]); this.actions[0].play(); // Check if the label exists in the container const hasLabel = container.children.some( (child) => child instanceof CSS2DObject ); if (hasLabel) { console.log("👀 Label Exists"); // This log is printed but the label is not visible } else { console.log("🤦♀️ Nothing"); } }); } }
- 参考官方标签示例格式为立方体添加标签,仍未显示;
- 调整标签的位置值、文字颜色及背景颜色,无任何变化。
解决方法
1. 修正CSS2DRenderer的挂载位置
canvas是HTML替换元素,内部无法容纳其他DOM节点,你之前把标签渲染容器挂载到canvas里会被浏览器忽略。改成挂载到body下:
// 替换原canvas.appendChild代码 document.body.appendChild(labelRenderer.domElement);
同时给标签容器设置pointer-events: none,避免遮挡canvas的交互:
labelRenderer.domElement.style.pointerEvents = "none";
2. 确认相机图层与标签匹配
确保相机启用了标签所在的图层(默认是0层),如果相机被设置过其他图层,需要同步开启:
camera.layers.enable(0);
3. 检查标签是否在相机视锥体内
如果标签位置超出相机可视范围也会看不到,可先将标签放在模型正上方测试:
labelText.position.set(0, 1, 0); // 立方体顶部位置
4. 确认CSS2D依赖已正确导入
如果使用ES模块,需确保导入了CSS2D相关类:
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
内容的提问来源于stack exchange,提问作者Lenson-Lee
相关产品推荐
相关产品推荐

