You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:46:02